/** * 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); }
/** * Removes a file in this project. * * @param jf the file to be removed */ public void remove(JavaFile jf) { files.remove(jf.getPath()); }
/** * 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); } }
@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(); }
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); }