private <T> void readModuleDescriptorsFromFolder( IFile file, Set<IFile> excludes, List<T> result, boolean refreshFiles, DescriptorReader<T> reader) { if (!needProcess(file, excludes)) return; if (refreshFiles) { FileSystem.getInstance().refresh(file); } // if this is a jar dir, we need to go to modules sub dir or check for META-INF/module.xml // if this is just good old plain directory, we check every file in it if (file.getPath().endsWith(JAR + JAR_SEPARATOR)) { IFile moduleXml = file.getDescendant(META_INF).getDescendant(MODULE_XML); if (moduleXml.exists() && !moduleXml.isDirectory()) { ModuleDescriptor moduleDescriptor = loadModuleDescriptor(moduleXml); if (moduleDescriptor != null) { T descriptor = reader.read(new ModuleHandle(moduleXml, moduleDescriptor)); if (descriptor != null) { result.add(descriptor); } } } else { IFile dirInJar = file.getDescendant(MODULES_DIR); if (dirInJar.exists() && dirInJar.isDirectory()) { readModuleDescriptorsFromFolder(dirInJar, excludes, result, refreshFiles, reader); } } } else { // first, we read from files // this way all modules roots, sources/classes folders are in excludes and we do not even go // into them List<IFile> children = file.getChildren(); ArrayList<IFile> folders = new ArrayList<IFile>(); for (IFile child : children) { if (!child.isDirectory()) { readModuleDescriptorsFromFile(child, excludes, result, refreshFiles, reader); } else { folders.add(child); } } // now read from folders for (IFile child : folders) { readModuleDescriptorsFromFolder(child, excludes, result, refreshFiles, reader); } } }
// FIXME: MPS-19756 // TODO: get rid of this code - generate the deployment descriptor during build process protected void updatePackagedDescriptor() { // things to do: // 1) load/prepare stub libraries (getAdditionalJavaStubPaths) from sources descriptor // 2) load/prepare stub model roots from sources descriptor // 3) load libraries from deployment descriptor (/classes_gen ?) // possible cases: // 1) without deployment descriptor (nothing to do; todo: ?) // 2) with deployment descriptor, without sources (to do: 3) // 3) with deployment descriptor, with sources (to do: 1,2,3) if (!isPackaged()) { return; } ModuleDescriptor descriptor = getModuleDescriptor(); if (descriptor == null) { return; } DeploymentDescriptor deplDescriptor = descriptor.getDeploymentDescriptor(); if (deplDescriptor == null) { return; } final IFile bundleHomeFile = getDescriptorFile().getBundleHome(); if (bundleHomeFile == null) { return; } IFile bundleParent = bundleHomeFile.getParent(); if (bundleParent == null || !bundleParent.exists()) { return; } IFile sourcesDescriptorFile = ModulesMiner.getSourceDescriptorFile(getDescriptorFile(), deplDescriptor); if (sourcesDescriptorFile == null) { // todo: for now it's impossible assert descriptor instanceof DeploymentDescriptor; } else { assert !(descriptor instanceof DeploymentDescriptor); } // 1 && 2 if (sourcesDescriptorFile != null) { // stub libraries // todo: looks like module.xml contains info about model libs // ignore stub libraries from source module descriptor, use libs from DeploymentDescriptor descriptor.getAdditionalJavaStubPaths().clear(); // stub model roots List<ModelRootDescriptor> toRemove = new ArrayList<ModelRootDescriptor>(); List<ModelRootDescriptor> toAdd = new ArrayList<ModelRootDescriptor>(); for (ModelRootDescriptor rootDescriptor : descriptor.getModelRootDescriptors()) { String rootDescriptorType = rootDescriptor.getType(); if (rootDescriptorType.equals(PersistenceRegistry.JAVA_CLASSES_ROOT)) { // trying to load old format from deployment descriptor String pathElement = rootDescriptor.getMemento().get("path"); boolean update = false; Memento newMemento = new MementoImpl(); if (pathElement != null) { // See JavaSourceStubModelRoot & JavaClassStubsModelRoot load methods need to replace // with super String convertedPath = convertPath(pathElement, bundleHomeFile, sourcesDescriptorFile, descriptor); if (convertedPath != null) { newMemento.put("path", convertedPath); update = true; } } else { // trying to load new format : replacing paths like **.jar!/module -> String contentPath = rootDescriptor.getMemento().get(FileBasedModelRoot.CONTENT_PATH); List<String> paths = new LinkedList<String>(); for (Memento sourceRoot : rootDescriptor.getMemento().getChildren(FileBasedModelRoot.SOURCE_ROOTS)) { paths.add(contentPath + File.separator + sourceRoot.get("location")); } newMemento.put(FileBasedModelRoot.CONTENT_PATH, bundleParent.getPath()); Memento newMementoChild = newMemento.createChild(FileBasedModelRoot.SOURCE_ROOTS); for (String path : paths) { String convertedPath = convertPath(path, bundleHomeFile, sourcesDescriptorFile, descriptor); if (convertedPath != null) { newMementoChild.put( "location", convertedPath.replace(newMemento.get(FileBasedModelRoot.CONTENT_PATH), "")); update = true; } } } if (update) { toAdd.add(new ModelRootDescriptor(rootDescriptorType, newMemento)); } toRemove.add(rootDescriptor); } } descriptor.getModelRootDescriptors().removeAll(toRemove); descriptor.getModelRootDescriptors().addAll(toAdd); } // 3 for (String jarFile : deplDescriptor.getLibraries()) { IFile jar = jarFile.startsWith("/") ? myFileSystem.getFile(PathManager.getHomePath() + jarFile) : bundleParent.getDescendant(jarFile); if (jar.exists()) { String path = jar.getPath(); descriptor.getAdditionalJavaStubPaths().add(path); descriptor.getModelRootDescriptors().add(ModelRootDescriptor.getJavaStubsModelRoot(jar)); } } }
@Override public String expandPath(@Nullable String path) { if (path == null) { return null; } if (moduleSourceDir != null) { for (String macro : MacrosFactory.descriptors) { if (path.startsWith(macro)) { String relPath = path.substring(path.indexOf('}') + 1); return IFileUtils.getCanonicalPath(moduleSourceDir.getDescendant(relPath)); } } } if (path.startsWith("${")) { int index = path.indexOf("}"); if (index == -1) { reporter.report("invalid macro in `" + path + "'", null, null); return path; } String macroName = path.substring(2, index); SNode found = null; for (SNode macro : SLinkOperations.getTargets( SNodeOperations.getAncestor( originalModule, "jetbrains.mps.build.structure.BuildProject", false, false), "macros", true)) { if (!(SNodeOperations.isInstanceOf( macro, "jetbrains.mps.build.structure.BuildFolderMacro"))) { continue; } if (eq_krgnbt_a0c0f0d0f4(SPropertyOperations.getString(macro, "name"), macroName)) { found = SNodeOperations.cast(macro, "jetbrains.mps.build.structure.BuildFolderMacro"); break; } } if (found == null) { reporter.report("macro is not declared in build script: " + path, null, null); return path; } String localPath = BehaviorReflection.invokeVirtual( String.class, SLinkOperations.getTarget(found, "defaultPath", true), "virtual_getLocalPath_5481553824944787364", new Object[] { (genContext != null ? Context.defaultContext(genContext) : Context.defaultContext()) }); if (localPath == null) { if (genContext != null) { genContext.showWarningMessage( found, "cannot resolve local path: " + path + ", macro has no default value"); } return path; } String relPath = path.substring(index + 1); return IFileUtils.getCanonicalPath( FileSystem.getInstance().getFileByPath(localPath).getDescendant(relPath)); } return path; }
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); }