Пример #1
0
 /**
  * Removes a file with a given name and its related files.
  *
  * @param pathname the name of the file to be removed
  */
 public void removeJavaFile(String pathname) {
   for (JavaFile jf : getJavaFiles()) {
     if (pathname.compareTo(jf.getPath()) == 0) {
       JavaClass.removeClassesRelatedTo(jf);
     }
   }
   cleanJavaProjects();
 }
  /**
   * Translates the body of the package and writes it to the output stream.
   *
   * @param out The output stream.
   * @return The output stream.
   */
  public Printer translate(Printer out) {
    // Include the header file
    out.p("#include \"").p(getFilename()).pln(".h\"").pln();

    // Print the array template specializations for the classes in this package
    out.pln("namespace __rt {").incr();
    for (JavaFile f : files) {
      for (JavaClass cls : f.getClasses()) {
        cls.translateArrayTemplate(out);
      }
    }
    out.decr().pln("}").pln();

    // Add the namespace
    for (String part : pkg) {
      out.indent().p("namespace ").p(part).pln(" {").incr();
    }

    // Print all the files in the package
    for (JavaFile f : files) {
      for (JavaClass cls : f.getClasses()) {
        cls.translate(out).pln();
      }
      out.pln();
    }

    // Close the namespace
    for (int i = 0; i < pkg.size(); i++) {
      out.decr().indent().pln("}");
    }

    // If this package contains the main file, print the main method here
    if (null != main) {
      out.pln("int main(int argc, char *argv[]) {").incr();
      out.indent().pln("__rt::Ptr<__rt::Array<String> > args = new __rt::Array<String>(argc-1);");
      out.indent().pln("for (int i = 1; i < argc; i++) {").incr();
      out.indent().pln("(*args)[i-1] = __rt::literal(argv[i]);");
      out.decr().indent().pln("}");
      out.indent();
      if (!getNamespace().equals("")) out.p(getNamespace()).p("::");
      out.p("__").p(main.getPublicClass().getName()).pln("::main$array1_String(args);");
      out.decr().pln("}");
    }

    return out;
  }
  /**
   * Writes the C++ header for the package to the specified output stream.
   *
   * @param out The output stream.
   * @return The output stream.
   */
  public Printer translateHeader(Printer out) {
    // Get any imports
    Set<JavaPackage> using = new HashSet<JavaPackage>();
    for (JavaFile file : files) {
      Set<JavaPackage> imports = file.getImports();
      for (JavaPackage i : imports) {
        if (!i.getPath().equals(getPath())) using.add(i);
      }
    }

    // Include any imported headers
    out.pln("#pragma once").pln();
    out.pln("#include <iostream>");
    out.pln("#include <sstream>").pln();
    out.pln("#include \"include/java_lang.h\"");
    for (JavaPackage i : using) {
      out.p("#include \"").p(i.getFilename()).pln(".h\"");
    }

    // Declare namespaces being used
    out.pln().pln("using namespace java::lang;");
    for (JavaPackage i : using) {
      out.p("using namespace ").p(i.getNamespace()).pln(";");
    }
    out.pln();

    // Add the namespace
    for (String part : pkg) {
      out.indent().p("namespace ").p(part).pln(" {").incr();
    }

    // Declare the class structs
    for (JavaFile file : files) {
      file.orderClasses();
      for (JavaClass cls : file.getClasses()) {
        String className = cls.getName();
        out.indent().p("struct __").p(className).pln(";");
        out.indent().p("struct __").p(className).pln("_VT;");
        out.pln()
            .indent()
            .p("typedef __rt::Ptr<__")
            .p(className)
            .p("> ")
            .p(className)
            .pln(";")
            .pln();
      }
    }

    // Print header structs
    for (JavaFile file : files) {
      for (JavaClass cls : file.getClasses()) {
        cls.translateHeader(out).pln();
      }
    }

    // Close the namespace
    for (int i = 0; i < pkg.size(); i++) {
      out.decr().indent().pln("}");
    }

    return out;
  }
 /**
  * Recursively orders files based on dependencies.
  *
  * @param file The file to add to the list.
  */
 private void order(JavaFile file) {
   if (file.isMain()) main = file;
   if (files.contains(file)) return;
   if (file.getPublicClass().hasParent()) order(file.getPublicClass().getParent().getFile());
   files.add(file);
 }
Пример #5
0
 /**
  * Removes a file in this project.
  *
  * @param jf the file to be removed
  */
 public void remove(JavaFile jf) {
   files.remove(jf.getPath());
 }
Пример #6
0
 /**
  * Adds a file contained in this project.
  *
  * @param jfile the file to be added
  */
 public void addJavaFile(JavaFile jfile) {
   if (files.get(jfile.getPath()) == null) {
     files.put(jfile.getPath(), jfile);
   }
 }
Пример #7
0
    @Override
    public void onCompilationResult(CompilationResult cr) {
      Set<String> classesWithErrors = new HashSet<String>();
      if (cr.getErrors() != null) {
        myTracer.push("handling errors", false);
        for (final CategorizedProblem cp : cr.getErrors()) {
          String fileName = new String(cp.getOriginatingFileName());
          final String fqName =
              NameUtil.namespaceFromPath(
                  fileName.substring(0, fileName.length() - MPSExtentions.DOT_JAVAFILE.length()));
          classesWithErrors.add(fqName);

          SModule containingModule = myContainingModules.get(fqName);
          assert containingModule != null;
          JavaFile javaFile = myModuleSources.get(containingModule).getJavaFile(fqName);

          String messageString = new String(cp.getOriginatingFileName()) + " : " + cp.getMessage();

          // final SNode nodeToShow = getNodeByLine(cp, fqName);

          Object hintObject = new FileWithPosition(javaFile.getFile(), cp.getSourceStart());

          String errMsg = messageString + " (line: " + cp.getSourceLineNumber() + ")";
          if (cp.isWarning()) {
            myMessages.add(createMessage(MessageKind.WARNING, errMsg, hintObject));
          } else {
            if (myOutputtedErrors == 0) {
              myMessages.add(createMessage(MessageKind.ERROR, "Compilation problems", null));
              myMessages.add(
                  createMessage(
                      MessageKind.INFORMATION,
                      "Modules: "
                          + myModules.toString()
                          + "\nClasspath: "
                          + myClassPathItems
                          + "\n",
                      null));
            }
            if (myOutputtedErrors < MAX_ERRORS) {
              myOutputtedErrors++;
              myMessages.add(createMessage(MessageKind.ERROR, errMsg, hintObject));
            }
          }
        }
        myTracer.pop();

        myErrorCount += cr.getErrors().length;
      }

      myTracer.push("storing files", false);
      for (ClassFile cf : cr.getClassFiles()) {
        String fqName = convertCompoundToFqName(cf.getCompoundName());
        String containerClassName = fqName;
        if (containerClassName.contains("$")) {
          int index = containerClassName.indexOf('$');
          containerClassName = containerClassName.substring(0, index);
        }
        if (myContainingModules.containsKey(containerClassName)) {
          SModule m = myContainingModules.get(containerClassName);
          myChangedModules.add(m);
          File classesGen = new File(getJavaFacet(m).getClassesGen().getPath());
          String packageName = NameUtil.namespaceFromLongName(fqName);
          File outputDir =
              new File(classesGen + File.separator + NameUtil.pathFromNamespace(packageName));
          if (!outputDir.exists()) {
            if (!outputDir.mkdirs()) {
              throw new RuntimeException("Can't create " + outputDir.getPath() + " directory");
            }
          }
          String className = NameUtil.shortNameFromLongName(fqName);
          File output = new File(outputDir, className + ".class");
          if (!classesWithErrors.contains(containerClassName)) {
            FileOutputStream os = null;
            try {
              os = new FileOutputStream(output);
              os.write(cf.getBytes());
            } catch (IOException e) {
              String errMsg = "Can't write to " + output.getAbsolutePath();
              myMessages.add(createMessage(MessageKind.ERROR, errMsg, null));
            } finally {
              if (os != null) {
                try {
                  os.close();
                } catch (IOException e) {
                  myHandler.handle(createMessage(MessageKind.ERROR, e.toString(), e));
                }
              }
            }
          } else {
            if (output.exists() && !(output.delete())) {
              String errMsg = "Can't delete " + output.getPath();
              myMessages.add(createMessage(MessageKind.ERROR, errMsg, null));
            }
          }
        } else {
          String errMsg =
              "I don't know in which module's output path I should place class file for " + fqName;
          myMessages.add(createMessage(MessageKind.ERROR, errMsg, null));
        }
      }
      myTracer.pop();
    }
Пример #8
0
  private MPSCompilationResult compile(Set<SModule> modules, JavaCompilerOptions compilerOptions) {
    boolean hasAnythingToCompile = false;
    List<IMessage> messages = new ArrayList<IMessage>();

    for (SModule m : modules) {
      if (isExcluded(m)) continue;

      hasAnythingToCompile = true;
    }

    if (!hasAnythingToCompile) {
      return new MPSCompilationResult(0, 0, false, Collections.<SModule>emptySet());
    }

    JavaCompiler compiler = new JavaCompiler();
    boolean hasJavaToCompile = false;
    boolean hasFilesToCopyOrDelete = false;

    myTracer.push("preparing to compile", false);
    Set<SModule> modulesWithRemovals = new HashSet<SModule>();
    for (SModule m : modules) {
      if (areClassesUpToDate(m)) continue;

      if (!getJavaFacet(m).isCompileInMps()) {
        String text =
            "Module which compiled in IDEA depends on module which has to be compiled in MPS:"
                + m.getModuleName();
        messages.add(createMessage(MessageKind.WARNING, text, m));
        myHandler.handle(createMessage(MessageKind.INFORMATION, text, m));
        continue;
      }

      ModuleSources sources = getModuleSources(m);
      hasFilesToCopyOrDelete |= !sources.isResourcesUpToDate();
      hasJavaToCompile |= !sources.isJavaUpToDate();

      for (File f : sources.getFilesToDelete()) {
        //noinspection ResultOfMethodCallIgnored
        f.delete();
        modulesWithRemovals.add(m);
      }

      for (JavaFile f : sources.getFilesToCompile()) {
        compiler.addSource(f.getClassName(), f.getContents());
        myContainingModules.put(f.getClassName(), m);
      }
    }
    myTracer.pop();

    if (!hasJavaToCompile && !hasFilesToCopyOrDelete) {
      return new MPSCompilationResult(0, 0, false, Collections.<SModule>emptySet(), messages);
    }

    myTracer.push("invalidating classpath", false);
    for (SModule module : modulesWithRemovals) {
      invalidateCompiledClasses(module);
    }
    myTracer.pop();

    Set<SModule> changedModules = new HashSet<SModule>();
    MyCompilationResultAdapter listener = null;
    if (hasJavaToCompile) {
      myTracer.push("compiling java", false);
      IClassPathItem classPathItems = computeDependenciesClassPath(modules);
      listener = new MyCompilationResultAdapter(modules, classPathItems, messages);
      compiler.addCompilationResultListener(listener);
      myTracer.push("eclipse compiler", true);

      if (compilerOptions == null) {
        compiler.compile(classPathItems);
      } else {
        compiler.compile(classPathItems, compilerOptions);
      }
      myTracer.pop();
      changedModules.addAll(listener.myChangedModules);
      compiler.removeCompilationResultListener(listener);
      myTracer.pop();
    }

    myTracer.push("copying resources", false);
    for (SModule module : modules) {
      ModuleSources sources = getModuleSources(module);
      IFile classesGen = getJavaFacet(module).getClassesGen();
      if (classesGen == null) {
        continue;
      }
      for (ResourceFile toCopy : sources.getResourcesToCopy()) {
        String fqName = toCopy.getPath();

        fqName = fqName.substring(0, fqName.length() - toCopy.getFile().getName().length());
        String path = fqName.replace('/', File.separatorChar) + toCopy.getFile().getName();

        if (new File(toCopy.getFile().getAbsolutePath()).exists()) {
          FileUtil.copyFile(
              new File(toCopy.getFile().getAbsolutePath()),
              new File(classesGen.getDescendant(path).getPath()));
        }
      }
    }
    myTracer.pop();

    myTracer.push("updating classpath", false);
    for (SModule module : changedModules) {
      invalidateCompiledClasses(module);
    }
    myTracer.pop();

    for (SModule module : modulesWithRemovals) {
      if (!changedModules.contains(module)) {
        myHandler.handle(
            createMessage(
                MessageKind.WARNING,
                "Module with removals not in changed modules: " + module,
                module));
      }
    }

    // todo: check possibility of this statements
    if (hasJavaToCompile && changedModules.isEmpty()) {
      myHandler.handle(
          createMessage(
              MessageKind.ERROR, "has java to compile but changed modules is empty", null));
    }
    if (!hasJavaToCompile && !changedModules.isEmpty()) {
      myHandler.handle(
          createMessage(
              MessageKind.ERROR, "has not java to compile but changed modules is not empty", null));
    }

    return new MPSCompilationResult(
        listener == null ? 0 : listener.getErrorCount(), 0, false, changedModules, messages);
  }