예제 #1
0
파일: ModulesMiner.java 프로젝트: sprig/MPS
  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);
      }
    }
  }
예제 #2
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));
      }
    }
  }
예제 #3
0
    @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;
    }
예제 #4
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);
  }