Search in sources :

Example 1 with RuntimeEnvironment

use of org.eclipse.n4js.runner.extension.RuntimeEnvironment in project n4js by eclipse.

the class RunnerFrontEnd method configureRuntimeEnvironment.

/**
 * Configures provided configuration based on the {@link RunConfiguration#getRuntimeEnvironment() runtime
 * environment} value it stores.
 *
 * Recomputes {@link RunConfiguration#getInitModules() init modules} and {@link RunConfiguration#getExecModule()
 * exec module} based on current state of the workspace.
 *
 * @param config
 *            the runtime configuration whose derived values are computed.
 */
public void configureRuntimeEnvironment(RunConfiguration config, Iterable<IN4JSProject> projects) {
    RuntimeEnvironment runtimeEnvironment = config.getRuntimeEnvironment();
    Optional<IN4JSProject> findRuntimeEnvironmentProject = hRuntimeEnvironments.findRuntimeEnvironmentProject(runtimeEnvironment, projects);
    if (findRuntimeEnvironmentProject.isPresent()) {
        IN4JSProject runtimeEnvironmentProject = findRuntimeEnvironmentProject.get();
        // 3) collect custom(!) init modules based on selected runtime environment
        final List<String> initModulePaths = getInitModulesPathsFrom(runtimeEnvironmentProject);
        config.setInitModules(initModulePaths);
        // 4) find compiled .js file to be executed first (the "executionModule" of the runtime environment)
        Optional<String> executionModule = getExecModulePathFrom(runtimeEnvironmentProject);
        if (executionModule.isPresent()) {
            config.setExecModule(executionModule.get());
        }
    }
}
Also used : RuntimeEnvironment(org.eclipse.n4js.runner.extension.RuntimeEnvironment) IN4JSProject(org.eclipse.n4js.projectModel.IN4JSProject)

Example 2 with RuntimeEnvironment

use of org.eclipse.n4js.runner.extension.RuntimeEnvironment in project n4js by eclipse.

the class RuntimeEnvironmentsHelper method recursiveCollectRlFromChain.

private void recursiveCollectRlFromChain(IN4JSProject runtimeEnvironment, Collection<IN4JSProject> collection) {
    Optional<String> extended = runtimeEnvironment.getExtendedRuntimeEnvironmentId();
    if (extended.isPresent()) {
        String id = extended.get();
        List<IN4JSProject> extendedRE = from(getAllProjects()).filter(p -> id.equals(p.getProjectId())).toList();
        if (extendedRE.isEmpty()) {
            return;
        }
        if (extendedRE.size() > 1) {
            LOGGER.debug("multiple projects match id " + id);
            LOGGER.error(new RuntimeException("Cannot obtain transitive list of provided libraries"));
            return;
        }
        IN4JSProject extendedRuntimeEnvironemnt = extendedRE.get(0);
        recursiveProvidedRuntimeLibrariesCollector(extendedRuntimeEnvironemnt.getProvidedRuntimeLibraries(), collection, p -> isRuntimeLibrary(p));
        recursiveCollectRlFromChain(extendedRuntimeEnvironemnt, collection);
    }
}
Also used : InsolvableRuntimeEnvironmentException(org.eclipse.n4js.runner.exceptions.InsolvableRuntimeEnvironmentException) Inject(com.google.inject.Inject) IN4JSCore(org.eclipse.n4js.projectModel.IN4JSCore) IN4JSSourceContainerAware(org.eclipse.n4js.projectModel.IN4JSSourceContainerAware) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) Logger(org.apache.log4j.Logger) Optional(com.google.common.base.Optional) FluentIterable.from(com.google.common.collect.FluentIterable.from) Map(java.util.Map) RuntimeEnvironment(org.eclipse.n4js.runner.extension.RuntimeEnvironment) SoureContainerAwareDependencyTraverser(org.eclipse.n4js.validation.helper.SoureContainerAwareDependencyTraverser) Iterator(java.util.Iterator) Predicate(java.util.function.Predicate) Collection(java.util.Collection) IN4JSProject(org.eclipse.n4js.projectModel.IN4JSProject) Set(java.util.Set) Collectors(java.util.stream.Collectors) ProjectType(org.eclipse.n4js.n4mf.ProjectType) DependencyCycleDetectedException(org.eclipse.n4js.runner.exceptions.DependencyCycleDetectedException) AbstractMap(java.util.AbstractMap) List(java.util.List) IN4JSArchive(org.eclipse.n4js.projectModel.IN4JSArchive) Entry(java.util.Map.Entry) Logger.getLogger(org.apache.log4j.Logger.getLogger) IN4JSProject(org.eclipse.n4js.projectModel.IN4JSProject)

Example 3 with RuntimeEnvironment

use of org.eclipse.n4js.runner.extension.RuntimeEnvironment in project n4js by eclipse.

the class RuntimeEnvironmentsHelper method containsAllCompatible.

/**
 * Compares two provided lists of {@link IN4JSProject}. Assumes both contain instances of type
 * {@link ProjectType#RUNTIME_ENVIRONMENT}. Checks if either all elements of latter list are contained in first one,
 * or if all elements of latter one are compatible (are in extend chain) of elements of the first one. If this check
 * holds returns true, otherwise false (also when either of the lists is empty)
 *
 * @param runnerEnvironments
 *            lists which must contain (might be indirectly via extend chain) elements of latter list
 * @param requiredEnvironments
 *            lists that is checked if it is supported by first one
 * @return true if all elements of latter list are (directly or indirectly) compatible with elements of the first
 *         list.
 */
public boolean containsAllCompatible(List<RuntimeEnvironment> runnerEnvironments, List<RuntimeEnvironment> requiredEnvironments) {
    if (runnerEnvironments.isEmpty() || requiredEnvironments.isEmpty()) {
        LOGGER.debug("cannot compare empty runtime environments lists");
        return false;
    }
    if (runnerEnvironments.containsAll(requiredEnvironments))
        return true;
    // check compatible / extend feature
    boolean result = true;
    List<IN4JSProject> allRuntimeEnvironments = from(getAllProjects()).filter(p -> isRuntimeEnvironemnt(p)).toList();
    Map<IN4JSProject, List<String>> reExtendedEnvironments = allRuntimeEnvironments.stream().map(re -> getExtendedRuntimeEnvironmentsNames(re, allRuntimeEnvironments)).collect(Collectors.toMap(e -> e.getKey(), e -> e.getValue()));
    // if runnerEnvironments (first param) would be single IN4JSProject (instead of collection)
    // code below could be simplified
    Iterator<RuntimeEnvironment> iterRuntimeEnvironment = runnerEnvironments.iterator();
    while (result && iterRuntimeEnvironment.hasNext()) {
        RuntimeEnvironment re = iterRuntimeEnvironment.next();
        List<IN4JSProject> listExtendedEnvironments = reExtendedEnvironments.keySet().stream().filter(p -> p.getProjectId().equals(re.getProjectId())).collect(Collectors.toList());
        if (listExtendedEnvironments.size() != 1) {
            LOGGER.debug("Multiple projects with name " + re.getProjectId() + " : " + listExtendedEnvironments.stream().map(p -> p.getProjectId()).reduce(new String(), (String r, String e) -> r += ", " + e));
            LOGGER.error("Cannot obtain project for name " + re.getProjectId());
            return false;
        }
        IN4JSProject extendedRuntimeEnvironment = listExtendedEnvironments.get(0);
        List<String> listExtendedEnvironemntsNames = reExtendedEnvironments.get(extendedRuntimeEnvironment);
        result = result && requiredEnvironments.stream().map(bre -> {
            return bre.getProjectId();
        }).allMatch(breName -> listExtendedEnvironemntsNames.contains(breName));
    }
    return result;
}
Also used : InsolvableRuntimeEnvironmentException(org.eclipse.n4js.runner.exceptions.InsolvableRuntimeEnvironmentException) Inject(com.google.inject.Inject) IN4JSCore(org.eclipse.n4js.projectModel.IN4JSCore) IN4JSSourceContainerAware(org.eclipse.n4js.projectModel.IN4JSSourceContainerAware) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) Logger(org.apache.log4j.Logger) Optional(com.google.common.base.Optional) FluentIterable.from(com.google.common.collect.FluentIterable.from) Map(java.util.Map) RuntimeEnvironment(org.eclipse.n4js.runner.extension.RuntimeEnvironment) SoureContainerAwareDependencyTraverser(org.eclipse.n4js.validation.helper.SoureContainerAwareDependencyTraverser) Iterator(java.util.Iterator) Predicate(java.util.function.Predicate) Collection(java.util.Collection) IN4JSProject(org.eclipse.n4js.projectModel.IN4JSProject) Set(java.util.Set) Collectors(java.util.stream.Collectors) ProjectType(org.eclipse.n4js.n4mf.ProjectType) DependencyCycleDetectedException(org.eclipse.n4js.runner.exceptions.DependencyCycleDetectedException) AbstractMap(java.util.AbstractMap) List(java.util.List) IN4JSArchive(org.eclipse.n4js.projectModel.IN4JSArchive) Entry(java.util.Map.Entry) Logger.getLogger(org.apache.log4j.Logger.getLogger) RuntimeEnvironment(org.eclipse.n4js.runner.extension.RuntimeEnvironment) IN4JSProject(org.eclipse.n4js.projectModel.IN4JSProject) ArrayList(java.util.ArrayList) List(java.util.List)

Example 4 with RuntimeEnvironment

use of org.eclipse.n4js.runner.extension.RuntimeEnvironment in project n4js by eclipse.

the class SupportingRunnerPropertyTester method test.

/**
 * Check if given receiver object is supported by given runner. Runner is specified by first arguments in args
 * parameter which is expected to be runner key value.
 *
 * @param receiver
 *            is either {@link FileEditorInput} or {@link IFile} to be check against runner.
 * @param property
 *            used to verify callers are invoking correct tester.
 * @param args
 *            expected to contain {@link String} representing runner key of the runner to test.
 * @param expectedValue
 *            not really used
 */
@Override
public boolean test(final Object receiver, final String property, final Object[] args, final Object expectedValue) {
    if (!PROPERTY_IS_SUPPORTING_RUNNER.equals(property)) {
        LOGGER.debug("invoked wrong property to test : " + property);
        return false;
    }
    // Input is neither a file nor file editor input.
    final Optional<IFile> file = getFileFromInput(receiver);
    if (!file.isPresent()) {
        return false;
    }
    // Cannot locate generated file, what to run?
    if (!generatedFileLocator.tryGetGeneratedSourceForN4jsFile(file.get()).isPresent()) {
        return false;
    }
    final Object arg0 = args[0];
    if (!(arg0 instanceof String)) {
        LOGGER.debug("invalid runner key value, should be String");
        return false;
    }
    final String runnerId = arg0.toString();
    final IRunnerDescriptor runnerDesc;
    try {
        runnerDesc = runnerRegistry.getDescriptor(runnerId);
    } catch (Exception e) {
        LOGGER.debug("invalid runner key value, no runner found for id: " + runnerId);
        return false;
    }
    final List<RuntimeEnvironment> compatibleRuntimeEnvironmets = newArrayList();
    try {
        compatibleRuntimeEnvironmets.addAll(findCompatibleRuntimeEnvironments(file.get()));
    } catch (final DependencyCycleDetectedException | InsolvableRuntimeEnvironmentException e) {
        LOGGER.info(e.getMessage());
        return false;
    }
    // TODO IDE-1351 remove the following hack once the library manager is in place
    if ("org.eclipse.n4js.runner.nodejs.NODEJS".equals(runnerDesc.getId())) {
        // the node-runner supports running without a custom runtime environment in the workspace
        final boolean haveCustomNodeRuntimeEnvironment = hRuntimeEnvironments.findRuntimeEnvironmentProject(RuntimeEnvironment.NODEJS).isPresent();
        if (!haveCustomNodeRuntimeEnvironment)
            return true;
    // otherwise:
    // there is a custom Node.js runtime environment -> continue with the ordinary checks ...
    }
    // TODO IDE-1393 connect testers with extension point
    if (!compatibleRuntimeEnvironmets.isEmpty() && "RE_NodeJS_Mangelhaft".equals(compatibleRuntimeEnvironmets.get(0).getProjectId())) {
        return true;
    }
    final boolean runnerToTestIsCompatible = compatibleRuntimeEnvironmets.contains(runnerDesc.getEnvironment());
    if (!runnerToTestIsCompatible) {
        LOGGER.debug("Runner with id '" + runnerId + "' does not support running selected file.");
        return false;
    }
    return true;
}
Also used : IFile(org.eclipse.core.resources.IFile) RuntimeEnvironment(org.eclipse.n4js.runner.extension.RuntimeEnvironment) IRunnerDescriptor(org.eclipse.n4js.runner.extension.IRunnerDescriptor) InsolvableRuntimeEnvironmentException(org.eclipse.n4js.runner.exceptions.InsolvableRuntimeEnvironmentException) DependencyCycleDetectedException(org.eclipse.n4js.runner.exceptions.DependencyCycleDetectedException) InsolvableRuntimeEnvironmentException(org.eclipse.n4js.runner.exceptions.InsolvableRuntimeEnvironmentException) DependencyCycleDetectedException(org.eclipse.n4js.runner.exceptions.DependencyCycleDetectedException)

Example 5 with RuntimeEnvironment

use of org.eclipse.n4js.runner.extension.RuntimeEnvironment in project n4js by eclipse.

the class RunnerHelper method getProjectExtendedDepsAndApiImplMapping.

/**
 * Returns a mapping from all API projects among <code>dependencies</code> to their corresponding implementation
 * project for implementation ID <code>implementationId</code>.
 * <p>
 * Special cases: if there are no API projects among the dependencies, this method will return an empty map in
 * {@link ApiUsage#concreteApiImplProjectMapping} and {@link ApiUsage#implementationIdRequired}<code>==false</code>;
 * otherwise, if <code>implementationId</code> is <code>null</code>, then this method will assert that there exists
 * exactly one implementation for the API projects among the dependencies and use that (stored in
 * {@link ApiUsage#implementationId}).
 * <p>
 * Throws exception in case of error given <code>throwOnError==true</code>, never returns null.
 *
 * @param runtimeEnvironment
 *            active runtime environment.
 * @param moduleToRun
 *            what to run.
 * @param implementationId
 *            might be <code>null</code>
 * @param throwOnError
 *            if true fast fail in erroneous situations. Otherwise tries to proceed in a meaningful way. State can
 *            then be queried on the ApiUsage instance.
 *
 * @return result wrapped in an {@link ApiUsage} instance.
 */
// TODO this methods could require some cleanup after the concepts of API-Implementation mappings stabilized...
public ApiUsage getProjectExtendedDepsAndApiImplMapping(RuntimeEnvironment runtimeEnvironment, URI moduleToRun, String implementationId, boolean throwOnError) {
    final LinkedHashSet<IN4JSProject> deps = new LinkedHashSet<>();
    // 1) add project containing the moduleToRun and its direct AND indirect dependencies
    final Optional<? extends IN4JSProject> project = n4jsCore.findProject(moduleToRun);
    if (project.isPresent() == false) {
        throw new RuntimeException("can't obtain containing project for moduleToRun: " + moduleToRun);
    }
    recursiveDependencyCollector(project.get(), deps, new RecursionGuard<>());
    // TODO need to add not only REs but also RLs they provide
    // 2) add the runtime environment project, REs it extends and RLs provided
    final Optional<IN4JSProject> reProject = getCustomRuntimeEnvironmentProject(runtimeEnvironment);
    if (reProject.isPresent()) {
        IN4JSProject re = reProject.get();
        recursiveExtendedREsCollector(re, deps);
    } else {
    // IDE-1359: don't throw exception to make runners work without user-defined runtime environment
    // (will be changed later when library manager is available!)
    // throw new RuntimeException("can't obtain runtime environment project for " + moduleToRun2);
    }
    // TODO actually we would like to return the dependencies in load order:
    // - RuntimeEnvironment boot
    // - all RuntimeLibrary boots (take deps2 between RLs into account)
    // - all other deps2 (order does not matter they just needs to be on path later)
    // - project to be called
    // maybe some in order DFS or something above?
    // manually transform to list, or is this one ok?
    final ApiImplMapping apiImplMapping = ApiImplMapping.of(deps, n4jsCore.findAllProjects());
    if (apiImplMapping.hasErrors()) {
        if (throwOnError)
            throw new IllegalStateException("the workspace setup contains errors related to API / implementation projects (check manifests of related projects):\n    " + Joiner.on("\n    ").join(apiImplMapping.getErrorMessages()));
    }
    if (apiImplMapping.isEmpty()) {
        return ApiUsage.of(new ArrayList<>(deps), Collections.<IN4JSProject, IN4JSProject>emptyMap(), apiImplMapping);
    }
    // there must be exactly one implementation for the API projects in the workspace
    if (implementationId == null) {
        final List<String> allImplIds = apiImplMapping.getAllImplIds();
        if (allImplIds.size() != 1) {
            if (throwOnError) {
                throw new IllegalStateException("no implementationId specified while several are available in the workspace: " + allImplIds);
            } else {
                // back out, further processing not possible without implementations id.
                return ApiUsage.of(new ArrayList<>(deps), Collections.emptyMap(), apiImplMapping, true);
            }
        } else {
            implementationId = allImplIds.get(0);
        }
    }
    final Map<IN4JSProject, IN4JSProject> apiImplProjectMapping = new LinkedHashMap<>();
    // projectIds of projects without an implementation
    final List<String> missing = new ArrayList<>();
    for (IN4JSProject dep : deps) {
        if (dep != null) {
            final String depId = dep.getProjectId();
            if (depId != null && apiImplMapping.isApi(depId)) {
                // so: dep is an API project ...
                final IN4JSProject impl = apiImplMapping.getImpl(depId, implementationId);
                if (impl != null) {
                    // so: impl is the implementation project for dep for implementation ID 'implementationId'
                    apiImplProjectMapping.put(dep, impl);
                } else {
                    // bad: no implementation for dep for implementation ID 'implementationId'
                    missing.add(depId);
                }
            }
        }
    }
    if (!missing.isEmpty()) {
        if (throwOnError) {
            throw new IllegalStateException("no implementation for implementation ID \"" + implementationId + "\" found for the following projects: " + Joiner.on(", ").join(missing));
        }
    }
    // / #-#-#-#-#-#-#-#-#-#-#-#-#-#-#
    // IDEBUG-506 look for additional dependencies, pulled in from api-impl project not yet processed:
    HashSet<IN4JSProject> processedDepProjects = deps;
    LinkedHashSet<IN4JSProject> tobeInspectedApiImplProjects = new LinkedHashSet<>();
    apiImplProjectMapping.entrySet().forEach(p -> {
        IN4JSProject v = p.getValue();
        if (!processedDepProjects.contains(v))
            tobeInspectedApiImplProjects.add(v);
    });
    // Collect transitive mappings. Populate with original ones.
    final Map<IN4JSProject, IN4JSProject> joinedApiImplProjectMapping = new LinkedHashMap<>(apiImplProjectMapping);
    while (!tobeInspectedApiImplProjects.isEmpty()) {
        // compute dependencies if necessary
        LinkedHashSet<IN4JSProject> batchedPivotDependencies = new LinkedHashSet<>();
        RecursionGuard<URI> guard = new RecursionGuard<>();
        for (IN4JSProject pivotProject : tobeInspectedApiImplProjects) {
            recursiveDependencyCollector(pivotProject, batchedPivotDependencies, guard);
        }
        tobeInspectedApiImplProjects.clear();
        List<IN4JSProject> batchedPivotNewDepList = batchedPivotDependencies.stream().filter(p -> null != p && !processedDepProjects.contains(p)).collect(Collectors.toList());
        // new Api-mapping
        apiImplMapping.enhance(batchedPivotNewDepList, n4jsCore.findAllProjects());
        // go over new dependencies and decide:
        for (IN4JSProject pivNewDep : batchedPivotNewDepList) {
            final String depId = pivNewDep.getProjectId();
            if (apiImplMapping.isApi(depId)) {
                // API-mapping
                if (joinedApiImplProjectMapping.containsKey(pivNewDep)) {
                // already done.
                } else {
                    // put new entry
                    IN4JSProject pivImpl = apiImplMapping.getImpl(depId, implementationId);
                    if (null != pivImpl) {
                        joinedApiImplProjectMapping.put(pivNewDep, pivImpl);
                        tobeInspectedApiImplProjects.add(pivImpl);
                    } else {
                        missing.add(depId);
                    }
                }
            } else {
                // no API.
                if (!processedDepProjects.contains(pivNewDep)) {
                    // add to deps
                    processedDepProjects.add(pivNewDep);
                }
            }
        }
    }
    if (!missing.isEmpty()) {
        if (throwOnError) {
            throw new IllegalStateException("no implementation for implementation ID \"" + implementationId + "\" found for the following projects: " + Joiner.on(", ").join(missing));
        }
    }
    return ApiUsage.of(implementationId, new ArrayList<>(deps), apiImplProjectMapping, apiImplMapping, missing);
}
Also used : LinkedHashSet(java.util.LinkedHashSet) BootstrapModule(org.eclipse.n4js.n4mf.BootstrapModule) URI(org.eclipse.emf.common.util.URI) Inject(com.google.inject.Inject) ResourceNameComputer(org.eclipse.n4js.utils.ResourceNameComputer) IN4JSCore(org.eclipse.n4js.projectModel.IN4JSCore) IN4JSSourceContainerAware(org.eclipse.n4js.projectModel.IN4JSSourceContainerAware) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) LinkedHashMap(java.util.LinkedHashMap) Strings(com.google.common.base.Strings) RunnerRegistry(org.eclipse.n4js.runner.extension.RunnerRegistry) N4JSGlobals(org.eclipse.n4js.N4JSGlobals) Optional(com.google.common.base.Optional) Map(java.util.Map) RecursionGuard(org.eclipse.n4js.utils.RecursionGuard) IRunnerDescriptor(org.eclipse.n4js.runner.extension.IRunnerDescriptor) RuntimeEnvironment(org.eclipse.n4js.runner.extension.RuntimeEnvironment) ApiImplMapping(org.eclipse.n4js.compare.ApiImplMapping) Path(java.nio.file.Path) LinkedHashSet(java.util.LinkedHashSet) Collections.emptyList(java.util.Collections.emptyList) Collection(java.util.Collection) IN4JSProject(org.eclipse.n4js.projectModel.IN4JSProject) Set(java.util.Set) Collectors(java.util.stream.Collectors) File(java.io.File) ProjectType(org.eclipse.n4js.n4mf.ProjectType) List(java.util.List) Lists.newArrayList(com.google.common.collect.Lists.newArrayList) IN4JSArchive(org.eclipse.n4js.projectModel.IN4JSArchive) AbstractSubGenerator(org.eclipse.n4js.generator.AbstractSubGenerator) Collections(java.util.Collections) FindArtifactHelper(org.eclipse.n4js.utils.FindArtifactHelper) Joiner(com.google.common.base.Joiner) ApiImplMapping(org.eclipse.n4js.compare.ApiImplMapping) ArrayList(java.util.ArrayList) Lists.newArrayList(com.google.common.collect.Lists.newArrayList) RecursionGuard(org.eclipse.n4js.utils.RecursionGuard) URI(org.eclipse.emf.common.util.URI) LinkedHashMap(java.util.LinkedHashMap) IN4JSProject(org.eclipse.n4js.projectModel.IN4JSProject)

Aggregations

RuntimeEnvironment (org.eclipse.n4js.runner.extension.RuntimeEnvironment)5 IN4JSProject (org.eclipse.n4js.projectModel.IN4JSProject)4 Optional (com.google.common.base.Optional)3 Inject (com.google.inject.Inject)3 ArrayList (java.util.ArrayList)3 Collection (java.util.Collection)3 HashSet (java.util.HashSet)3 List (java.util.List)3 Map (java.util.Map)3 Set (java.util.Set)3 Collectors (java.util.stream.Collectors)3 ProjectType (org.eclipse.n4js.n4mf.ProjectType)3 IN4JSArchive (org.eclipse.n4js.projectModel.IN4JSArchive)3 IN4JSCore (org.eclipse.n4js.projectModel.IN4JSCore)3 IN4JSSourceContainerAware (org.eclipse.n4js.projectModel.IN4JSSourceContainerAware)3 DependencyCycleDetectedException (org.eclipse.n4js.runner.exceptions.DependencyCycleDetectedException)3 InsolvableRuntimeEnvironmentException (org.eclipse.n4js.runner.exceptions.InsolvableRuntimeEnvironmentException)3 FluentIterable.from (com.google.common.collect.FluentIterable.from)2 AbstractMap (java.util.AbstractMap)2 Iterator (java.util.Iterator)2