Beispiel #1
0
 protected void readModules(FileMPSProject.ProjectDescriptor projDesc) {
   myErrors = null;
   //  load solutions
   Set<ModuleReference> existingModules = getModuleReferences();
   for (Path modulePath : projDesc.getModules()) {
     String path = modulePath.getPath();
     IFile descriptorFile = FileSystem.getInstance().getFileByPath(path);
     if (descriptorFile.exists()) {
       ModuleDescriptor descriptor =
           ModulesMiner.getInstance().loadModuleDescriptor(descriptorFile);
       if (descriptor != null) {
         ModulesMiner.ModuleHandle moduleHandle =
             new ModulesMiner.ModuleHandle(descriptorFile, descriptor);
         IModule m = ModuleRepositoryFacade.createModule(moduleHandle, this);
         ModuleReference moduleReference = m.getModuleReference();
         if (!(existingModules.remove(moduleReference))) {
           super.addModule(moduleReference);
         }
       } else {
         error("Can't load module from " + descriptorFile.getPath() + " Unknown file type.");
       }
     } else {
       error("Can't load module from " + descriptorFile.getPath() + " File doesn't exist.");
     }
   }
   for (ModuleReference ref : existingModules) {
     super.removeModule(ref);
   }
 }
Beispiel #2
0
 public ModuleDescriptor loadModuleDescriptor(IFile file) {
   try {
     String filePath = file.getPath();
     if (filePath.endsWith(SLASH_META_INF_MODULE_XML)) {
       DeploymentDescriptor deploymentDescriptor =
           DeploymentDescriptorPersistence.loadDeploymentDescriptor(file);
       ModuleDescriptor result = null;
       IFile realDescriptorFile = getRealDescriptorFile(filePath, deploymentDescriptor);
       if (realDescriptorFile != null) {
         result = loadModuleDescriptor(realDescriptorFile);
       }
       // TODO create module without sources
       if (result != null) {
         result.setDeploymentDescriptor(deploymentDescriptor);
         // TODO fix stubs
       }
       return result;
     } else {
       return DescriptorIOFacade.getInstance().fromFileType(file).readFromFile(file);
     }
   } catch (Exception t) {
     LOG.error("Fail to load module from descriptor " + file.getPath(), t);
     return null;
   }
 }
Beispiel #3
0
  private void processExcludes(
      @NotNull IFile descriptorFile, ModuleDescriptor descriptor, Set<IFile> excludes) {
    if (descriptor == null || descriptorFile.isReadOnly()) {
      return;
    }

    for (String p : descriptor.getSourcePaths()) {
      excludes.add(FileSystem.getInstance().getFileByPath(p));
    }

    IFile genPath = ProjectPathUtil.getGeneratorOutputPath(descriptorFile.getParent(), descriptor);
    if (genPath != null) {
      excludes.add(genPath);
      if (!descriptorFile.isReadOnly()) {
        FileSystem.getInstance().getFileByPath(FileGenerationUtil.getCachesPath(genPath.getPath()));
      }
    }

    IFile testsGenPath = ProjectPathUtil.getGeneratorTestsOutputPath(descriptorFile, descriptor);
    if (testsGenPath != null) {
      excludes.add(testsGenPath);
      if (!descriptorFile.isReadOnly()) {
        FileSystem.getInstance()
            .getFileByPath(FileGenerationUtil.getCachesPath(testsGenPath.getPath()));
      }
    }

    for (ModelRootDescriptor rootDescriptor : descriptor.getModelRootDescriptors()) {
      ModelRoot root = rootDescriptor.getRoot();
      if (root == null
          || root.getManager() != null && root.getManager() != LanguageID.JAVA_MANAGER) {
        continue;
      }

      excludes.add(FileSystem.getInstance().getFileByPath(root.getPath()));
    }

    IFile classesGen = ProjectPathUtil.getClassesGenFolder(descriptorFile.getParent(), false);
    if (classesGen != null) {
      excludes.add(classesGen);
    }

    // todo: specify what kind of descriptor can be input for this method
    if (descriptor instanceof LanguageDescriptor) {
      IFile generatorClassesGen =
          ProjectPathUtil.getClassesGenFolder(descriptorFile.getParent(), true);
      if (generatorClassesGen != null) {
        excludes.add(generatorClassesGen);
      }
    }

    for (String entry : descriptor.getAdditionalJavaStubPaths()) {
      excludes.add(FileSystem.getInstance().getFileByPath(entry));
    }
  }
Beispiel #4
0
  @Override
  public void rename(String newModelName, boolean changeFile) {
    assertCanChange();

    SModelReference oldName = getReference();
    fireBeforeModelRenamed(new SModelRenamedEvent(this, oldName.getModelName(), newModelName));

    // TODO update SModelId (if it contains modelName)
    // if(getReference().getModelId().getModelName() != null) { }
    SModelReference newModelReference =
        PersistenceFacade.getInstance()
            .createModelReference(
                getReference().getModuleReference(), getReference().getModelId(), newModelName);

    fireBeforeModelRenamed(newModelReference);
    changeModelReference(newModelReference);

    if (!changeFile) {
      save();
    } else {
      if (changeFile && !(getSource() instanceof FileDataSource)) {
        throw new UnsupportedOperationException("cannot change model file on non-file data source");
      }

      IFile oldFile = ((FileDataSource) getSource()).getFile();
      ModelRoot root = ModelRootUtil.getModelRoot(this);
      if (root instanceof DefaultModelRoot) {
        DefaultModelRoot defaultModelRoot = (DefaultModelRoot) root;
        String sourceRoot = null;
        for (String sr : defaultModelRoot.getFiles(FileBasedModelRoot.SOURCE_ROOTS)) {
          if (oldFile.getPath().startsWith(sr)) {
            // using the same sourceRoot
            sourceRoot = sr;
            break;
          }
        }
        try {
          IFile newFile =
              defaultModelRoot
                  .createSource(
                      newModelName,
                      FileUtil.getExtension(oldFile.getName()),
                      sourceRoot,
                      new HashMap<String, String>())
                  .getFile();
          newFile.getParent().mkdirs();
          newFile.createNewFile();
          changeModelFile(newFile);
          save();
          oldFile.delete();
        } catch (IOException e) {
          LOG.error("cannot rename " + getModelName() + ": " + e.getMessage());
          save();
        }
      }
    }

    fireModelRenamed(new SModelRenamedEvent(this, oldName.getModelName(), newModelName));
    fireModelRenamed(oldName);
  }
Beispiel #5
0
  private <T> void readModuleDescriptorsFromFile(
      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 (file.getName().endsWith(JAR)) {
      IFile jarRoot = FileSystem.getInstance().getFileByPath(file.getPath() + JAR_SEPARATOR);
      if (jarRoot != null) {
        readModuleDescriptorsFromFolder(jarRoot, excludes, result, refreshFiles, reader);
      }
    } else {
      if (!isModuleFile(file)) return;
      ModuleDescriptor moduleDescriptor = loadDescriptorOnly_internal(file, excludes);
      if (moduleDescriptor != null) {
        T descriptor = reader.read(new ModuleHandle(file, moduleDescriptor));
        if (descriptor != null) {
          result.add(descriptor);
        }
      }
    }
  }
Beispiel #6
0
 private static IFile getRefactoringsFile(IFile modelFile) {
   String modelPath = modelFile.getPath();
   String refactoringsPath =
       modelPath.substring(0, modelPath.length() - MPSExtentions.DOT_MODEL.length())
           + MPSExtentions.DOT_REFACTORINGS;
   return FileSystem.getInstance().getFileByPath(refactoringsPath);
 }
Beispiel #7
0
 private SNode convertLanguage(LanguageDescriptor source) {
   SNode result =
       SConceptOperations.createNewNode("jetbrains.mps.lang.project.structure.Language", null);
   result.setId(SNodeId.fromString("~root"));
   SModelOperations.addRootNode(myModel, result);
   fill(result, source);
   SPropertyOperations.set(result, "doNotGenerateAdapters", "" + source.isDoNotGenerateAdapters());
   SPropertyOperations.set(result, "genPath", source.getGenPath());
   SPropertyOperations.set(result, "languagePath", myFile.getPath());
   for (SModelReference ref : source.getAccessoryModels()) {
     SLinkOperations.getTargets(result, "accessoryModels", true).add(convert(ref));
   }
   for (GeneratorDescriptor descriptor : source.getGenerators()) {
     SLinkOperations.getTargets(result, "generator", true).add(convert(descriptor));
   }
   for (ModuleReference ref : source.getExtendedLanguages()) {
     SLinkOperations.getTargets(result, "extendedLanguages", true).add(convert(ref));
   }
   for (Dependency dep : source.getRuntimeModules()) {
     SLinkOperations.getTargets(result, "runtimeModules", true).add(convert(dep));
   }
   for (ModelRoot entry : source.getRuntimeStubModels()) {
     SLinkOperations.getTargets(result, "runtimeStubModels", true).add(convert(entry));
   }
   for (StubSolution sol : source.getStubSolutions()) {
     SLinkOperations.getTargets(result, "stubSolutions", true).add(convert(sol));
   }
   collectModels(result, source);
   return result;
 }
Beispiel #8
0
 @Override
 public String compute() {
   TreeFileChooser chooser = new TreeFileChooser();
   chooser.setMode(TreeFileChooser.MODE_DIRECTORIES);
   IFile result = chooser.showDialog();
   if (result == null) {
     return null;
   }
   return result.getPath();
 }
Beispiel #9
0
 public void doExecute(@NotNull final AnActionEvent event, final Map<String, Object> _params) {
   try {
     IModule module = ((SModelDescriptor) MapSequence.fromMap(_params).get("model")).getModule();
     TreeFileChooser treeFileChooser = new TreeFileChooser();
     treeFileChooser.setDirectoriesAreAlwaysVisible(true);
     treeFileChooser.setMode(TreeFileChooser.MODE_DIRECTORIES);
     final SModel sModel =
         ((SModelDescriptor) MapSequence.fromMap(_params).get("model")).getSModel();
     treeFileChooser.setFileFilter(
         new IFileFilter() {
           public boolean accept(IFile file) {
             return JavaCompiler.checkBaseModelMatchesSourceDirectory(
                 sModel, new File(file.getPath()));
           }
         });
     String generatorOutputPath = module.getGeneratorOutputPath();
     File initial = null;
     File output = new File(generatorOutputPath);
     if (output.exists()) {
       initial = output;
       File sourceRoot = new File(initial.getParentFile(), "source");
       if (!(sourceRoot.exists())) {
         sourceRoot = new File(initial.getParentFile(), "src");
       }
       initial = sourceRoot;
       if (sourceRoot.exists()) {
         File modelSource = new File(sourceRoot, NameUtil.pathFromNamespace(sModel.getLongName()));
         if (modelSource.exists()) {
           initial = modelSource;
         }
       }
     }
     if (initial != null) {
       treeFileChooser.setInitialFile(
           FileSystem.getInstance().getFileByPath(initial.getAbsolutePath()));
     }
     IFile result =
         treeFileChooser.showDialog(((Frame) MapSequence.fromMap(_params).get("frame")));
     if (result != null) {
       JavaCompiler javaCompiler =
           new JavaCompiler(
               ((IOperationContext) MapSequence.fromMap(_params).get("context")),
               module,
               new File(result.getPath()),
               false,
               sModel);
       javaCompiler.compile();
     }
   } catch (Throwable t) {
     if (log.isErrorEnabled()) {
       log.error("User's action execute method failed. Action:" + "GetModelContentsFromSource", t);
     }
   }
 }
Beispiel #10
0
  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);
      }
    }
  }
Beispiel #11
0
 private SNode convertSolution(SolutionDescriptor source) {
   SNode result =
       SConceptOperations.createNewNode("jetbrains.mps.lang.project.structure.Solution", null);
   result.setId(SNodeId.fromString("~root"));
   SModelOperations.addRootNode(myModel, result);
   fill(result, source);
   SPropertyOperations.set(result, "dontLoadClasses", "" + source.isDontLoadClasses());
   SPropertyOperations.set(result, "outputPath", source.getOutputPath());
   SPropertyOperations.set(result, "solutionPath", myFile.getPath());
   collectModels(result, source);
   return result;
 }
Beispiel #12
0
 private ModuleDescriptor loadDescriptorOnly_internal(IFile descriptorFile, Set<IFile> excludes) {
   try {
     ModuleDescriptor descriptor = loadModuleDescriptor(descriptorFile);
     if (descriptor != null) {
       processExcludes(descriptorFile, descriptor, excludes);
     }
     return descriptor;
   } catch (Exception t) {
     LOG.error("Fail to load module from descriptor " + descriptorFile.getPath(), t);
   }
   return null;
 }
Beispiel #13
0
  /**
   * Convert path from sources module descriptor for using on distribution /classes && /classes_gen
   * converts to bundle home path
   *
   * @param originalPath Original path from sources module descriptor
   * @return Converted path, null if path meaningless on packaged module
   */
  @Nullable
  private String convertPath(
      String originalPath,
      IFile bundleHome,
      IFile sourcesDescriptorFile,
      ModuleDescriptor descriptor) {
    MacroHelper macroHelper = MacrosFactory.forModuleFile(sourcesDescriptorFile);

    String canonicalPath = FileUtil.getCanonicalPath(originalPath).toLowerCase();

    // /classes && /classes_gen hack
    String suffix = descriptor.getCompileInMPS() ? CLASSES_GEN : CLASSES;
    if (canonicalPath.endsWith(suffix)) {
      // MacrosFactory based on original descriptor file because we use original descriptor file for
      // ModuleDescriptor reading, so all paths expanded to original descriptor file
      String classes = macroHelper.expandPath("${module}/" + suffix);
      if (FileUtil.getCanonicalPath(classes).equalsIgnoreCase(canonicalPath)) {
        return bundleHome.getPath();
      }
    } else if (FileUtil.getCanonicalPath(bundleHome.getPath()).equalsIgnoreCase(canonicalPath)) {
      return bundleHome.getPath();
    }

    // ${mps_home}/lib
    String mpsHomeLibPath =
        FileUtil.getCanonicalPath(PathManager.getHomePath() + File.separator + "lib").toLowerCase();
    if (canonicalPath.startsWith(mpsHomeLibPath)) {
      return canonicalPath;
    }

    // we used to keep originalPath if it has a macro not known to MPS here.
    // However, the check has been deprecated in 2012 and thus removed. I'm not 100% sure what
    // 'meaningless' in the contract of the method means. Of course, unknown macros make no sense
    // for us
    // and thus null is legitimate answer, OTOH, custom macros might have a lot of meaning to
    // someone else.
    //
    // ignore paths starts from ${module}/${project} etc
    return null;
  }
Beispiel #14
0
 public Path compute() {
   TreeFileChooser chooser = new TreeFileChooser();
   chooser.setExtensionFileFilter(
       MPSExtentions.DOT_LANGUAGE,
       MPSExtentions.DOT_SOLUTION,
       MPSExtentions.DOT_LIBRARY,
       MPSExtentions.DOT_DEVKIT);
   IFile file = chooser.showDialog(myOwner.getMainComponent());
   if (file == null) {
     return null;
   }
   return new Path(file.getPath());
 }
Beispiel #15
0
  public static void save(IFile modelFile, StructureModificationLog log) {
    IFile refactoringsFile = getRefactoringsFile(modelFile);
    refactoringsFile.createNewFile();

    Document document = new HistoryWriter().saveHistory(log);
    if (refactoringsFile.isReadOnly()) {
      LOG.error("Can't write to " + refactoringsFile.getPath());
      return;
    }

    try {
      JDOMUtil.writeDocument(document, refactoringsFile);
    } catch (IOException e) {
      LOG.error("Error in file " + refactoringsFile, e);
    }
  }
Beispiel #16
0
 @Nullable
 public static IFile getRealDescriptorFile(
     String filePath, DeploymentDescriptor deploymentDescriptor) {
   if (deploymentDescriptor.getSourcesJar() != null) {
     IFile moduleJar =
         FileSystem.getInstance()
             .getFileByPath(
                 filePath.substring(0, filePath.length() - SLASH_META_INF_MODULE_XML.length()));
     IFile sourcesJar = moduleJar.getParent().getDescendant(deploymentDescriptor.getSourcesJar());
     if (sourcesJar.exists() && deploymentDescriptor.getDescriptorFile() != null) {
       return FileSystem.getInstance()
           .getFileByPath(
               sourcesJar.getPath() + "!/module/" + deploymentDescriptor.getDescriptorFile());
     }
   }
   return null;
 }
Beispiel #17
0
 private SNode convertDevkit(DevkitDescriptor source) {
   SNode result =
       SConceptOperations.createNewNode("jetbrains.mps.lang.project.structure.DevKit", null);
   result.setId(SNodeId.fromString("~root"));
   SModelOperations.addRootNode(myModel, result);
   fill(result, source);
   SPropertyOperations.set(result, "devkitPath", myFile.getPath());
   for (ModuleReference ref : source.getExtendedDevkits()) {
     SLinkOperations.getTargets(result, "extendedDevkits", true).add(convert(ref));
   }
   for (ModuleReference ref : source.getExportedLanguages()) {
     SLinkOperations.getTargets(result, "exportedLanguages", true).add(convert(ref));
   }
   for (ModuleReference ref : source.getExportedSolutions()) {
     SLinkOperations.getTargets(result, "exportedSolutions", true).add(convert(ref));
   }
   return result;
 }
Beispiel #18
0
 public static StructureModificationLog load(IFile modelFile) {
   IFile refactoringsFile = getRefactoringsFile(modelFile);
   if (!refactoringsFile.exists()) return null;
   try {
     HistoryReaderHandler handler = new HistoryReaderHandler();
     JDOMUtil.createSAXParser().parse(JDOMUtil.loadSource(refactoringsFile), handler);
     return handler.getResult();
   } catch (SAXParseException e) {
     LOG.warning(refactoringsFile.getPath() + " line " + e.getLineNumber());
   } catch (IOException e) {
     LOG.error(e);
   } catch (SAXException e) {
     LOG.error(e);
   } catch (ParserConfigurationException e) {
     LOG.error(e);
   }
   return null;
 }
Beispiel #19
0
 public static ModuleDescriptor loadModuleDescriptor(
     IFile moduleDescriptorFile,
     TemplateQueryContext genContext,
     SNode originalModule,
     ModuleChecker.Reporter reporter) {
   MacroHelper helper =
       new ModuleLoaderUtils.ModuleMacroHelper(
           moduleDescriptorFile.getParent(), genContext, originalModule, reporter);
   String path = moduleDescriptorFile.getPath();
   if (path.endsWith(MPSExtentions.DOT_LANGUAGE)) {
     return LanguageDescriptorPersistence.loadLanguageDescriptor(moduleDescriptorFile, helper);
   } else if (path.endsWith(MPSExtentions.DOT_SOLUTION)) {
     return SolutionDescriptorPersistence.loadSolutionDescriptor(moduleDescriptorFile, helper);
   } else if (path.endsWith(MPSExtentions.DOT_DEVKIT)) {
     return DevkitDescriptorPersistence.loadDevKitDescriptor(moduleDescriptorFile);
   }
   throw new RuntimeException("unknown file type: " + moduleDescriptorFile.getName());
 }
Beispiel #20
0
  public void changeModelFile(IFile newModelFile) {
    assertCanChange();
    if (!(getSource() instanceof FileDataSource)) {
      throw new UnsupportedOperationException("cannot change model file on non-file data source");
    }

    FileDataSource source = (FileDataSource) getSource();
    if (source.getFile().getPath().equals(newModelFile.getPath())) return;

    IFile oldFile = source.getFile();
    jetbrains.mps.smodel.SModel model = getSModel();
    fireBeforeModelFileChanged(
        new SModelFileChangedEvent(model.getModelDescriptor(), oldFile, newModelFile));
    source.setFile(newModelFile);
    updateTimestamp();
    fireModelFileChanged(
        new SModelFileChangedEvent(model.getModelDescriptor(), oldFile, newModelFile));
  }
Beispiel #21
0
 private void invalidateCompiledClasses(SModule module) {
   IFile classesGen = getJavaFacet(module).getClassesGen();
   if (classesGen != null) {
     ClassPathFactory.getInstance().invalidate(Collections.singleton(classesGen.getPath()));
   }
 }
Beispiel #22
0
  // 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));
      }
    }
  }
  private <T> MultiMap<SModel, T> findCandidates(
      Collection<SModel> models,
      Set<T> elems,
      Consumer<SModel> processedModels,
      Function<T, UsageEntry> id) {
    // get all files in scope
    final ManyToManyMap<SModel, VirtualFile> scopeFiles = new ManyToManyMap<SModel, VirtualFile>();
    for (final SModel sm : models) {
      if (sm instanceof EditableSModel && ((EditableSModel) sm).isChanged()) {
        continue;
      }

      DataSource source = sm.getSource();
      // these are data sources this participant knows about
      if (!(source instanceof FileDataSource || source instanceof FilePerRootDataSource)) {
        continue;
      }

      /*
      This is a tmp fix for MPS-24151. See the issue to learn about the correct fix
       */
      if (!(sm instanceof DefaultSModelDescriptor)) {
        continue;
      }

      Collection<IFile> modelFiles = getDataSourceFiles(source);
      for (IFile modelFile : modelFiles) {
        String ext = FileUtil.getExtension(modelFile.getName());
        if (ext == null || modelFile.isDirectory()) {
          continue;
        }

        VirtualFile vf = VirtualFileUtils.getOrCreateVirtualFile(modelFile);
        if (vf == null) {
          LogManager.getLogger(MPSModelsFastFindSupport.class)
              .warn(
                  String.format(
                      "Model %s: virtual file not found for model file. Model file: %s",
                      sm.getName(), modelFile.getPath()));
          continue;
        }
        processedModels.consume(sm);
        scopeFiles.addLink(sm, vf);
      }
    }

    // filter files with usages
    ConcreteFilesGlobalSearchScope allFiles =
        new ConcreteFilesGlobalSearchScope(scopeFiles.getSecond());
    // process indexes
    MultiMap<SModel, T> result = new SetBasedMultiMap<SModel, T>();
    for (T elem : elems) {
      UsageEntry entry = id.apply(elem);

      Collection<VirtualFile> matchingFiles;

      try {
        matchingFiles = MPSModelsIndexer.getContainingFiles(entry, allFiles);
      } catch (ProcessCanceledException ce) {
        matchingFiles = Collections.emptyList();
      }

      // back-transform
      for (VirtualFile file : matchingFiles) {
        for (SModel m : scopeFiles.getBySecond(file)) {
          result.putValue(m, elem);
        }
      }
    }
    return result;
  }
  public static void saveLanguageDescriptor(
      IFile file, LanguageDescriptor descriptor, MacroHelper macroHelper) {
    if (file.isReadOnly()) {
      if (LOG.isEnabledFor(Priority.ERROR)) {
        LOG.error("Cant't save " + file.getPath());
      }
      return;
    }

    Element languageElement = new Element("language");
    languageElement.setAttribute("namespace", descriptor.getNamespace());
    String uuid = descriptor.getUUID();
    if (uuid != null) {
      languageElement.setAttribute("uuid", uuid);
    }
    if (descriptor.getGenPath() != null) {
      languageElement.setAttribute(
          "generatorOutputPath", macroHelper.shrinkPath(descriptor.getGenPath()));
    }

    Element models = new Element("models");
    ModuleDescriptorPersistence.saveModelRoots(
        models, descriptor.getModelRootDescriptors(), macroHelper);
    languageElement.addContent(models);

    if (!(descriptor.getModuleFacetDescriptors().isEmpty())) {
      Element facets = new Element("facets");
      ModuleDescriptorPersistence.saveFacets(
          facets, descriptor.getModuleFacetDescriptors(), macroHelper);
      languageElement.addContent(facets);
    }

    Element accessoryModels = new Element("accessoryModels");
    for (SModelReference model : SetSequence.fromSet(descriptor.getAccessoryModels())) {
      XmlUtil.tagWithAttribute(accessoryModels, "model", "modelUID", model.toString());
    }
    languageElement.addContent(accessoryModels);

    Element generators = new Element("generators");
    for (GeneratorDescriptor generatorDescriptor :
        ListSequence.fromList(descriptor.getGenerators())) {
      GeneratorDescriptorPersistence.saveGeneratorDescriptor(
          generators, generatorDescriptor, macroHelper);
    }
    languageElement.addContent(generators);

    if (!(descriptor.getAdditionalJavaStubPaths().isEmpty())) {
      Element stubModelEntries = new Element("stubModelEntries");
      ModuleDescriptorPersistence.saveStubModelEntries(
          stubModelEntries, descriptor.getAdditionalJavaStubPaths(), macroHelper);
      languageElement.addContent(stubModelEntries);
    }

    Element sourcePath = new Element("sourcePath");
    for (String p : descriptor.getSourcePaths()) {
      XmlUtil.tagWithAttribute(sourcePath, "source", "path", macroHelper.shrinkPath(p));
    }
    languageElement.addContent(sourcePath);

    ModuleDescriptorPersistence.saveDependencies(languageElement, descriptor);

    Element extendedLanguages = new Element("extendedLanguages");
    for (SModuleReference ref : SetSequence.fromSet(descriptor.getExtendedLanguages())) {
      XmlUtil.tagWithText(extendedLanguages, "extendedLanguage", ref.toString());
    }
    languageElement.addContent(extendedLanguages);

    try {
      OutputStream os = file.openOutputStream();
      JDOMUtil.writeDocument(new Document(languageElement), os);
    } catch (Exception e) {
      if (LOG.isEnabledFor(Priority.ERROR)) {
        LOG.error("", e);
      }
    }
    ModuleDescriptorPersistence.setTimestamp(descriptor, file);
  }