Example usage for com.google.common.collect ImmutableMap entrySet

List of usage examples for com.google.common.collect ImmutableMap entrySet

Introduction

In this page you can find the example usage for com.google.common.collect ImmutableMap entrySet.

Prototype

public final ImmutableSet<Entry<K, V>> entrySet() 

Source Link

Usage

From source file:com.facebook.buck.apple.project_generator.ProjectGenerator.java

/**
 * Create target level configuration entries.
 *
 * @param target      Xcode target for which the configurations will be set.
 * @param targetGroup Xcode group in which the configuration file references will be placed.
 * @param configurations  Configurations as extracted from the BUCK file.
 * @param overrideBuildSettings Build settings that will override ones defined elsewhere.
 * @param defaultBuildSettings  Target-inline level build settings that will be set if not already
 *                              defined.
 * @param appendBuildSettings   Target-inline level build settings that will incorporate the
 *                              existing value or values at a higher level.
 */// w  w  w  .  j a v  a  2 s .  c  om
private void setTargetBuildConfigurations(Function<String, Path> configurationNameToXcconfigPath,
        PBXTarget target, PBXGroup targetGroup,
        ImmutableMap<String, ImmutableMap<String, String>> configurations,
        ImmutableMap<String, String> overrideBuildSettings, ImmutableMap<String, String> defaultBuildSettings,
        ImmutableMap<String, String> appendBuildSettings) throws IOException {

    for (Map.Entry<String, ImmutableMap<String, String>> configurationEntry : configurations.entrySet()) {
        targetConfigNamesBuilder.add(configurationEntry.getKey());

        ImmutableMap<String, String> targetLevelInlineSettings = configurationEntry.getValue();

        XCBuildConfiguration outputConfiguration = target.getBuildConfigurationList()
                .getBuildConfigurationsByName().getUnchecked(configurationEntry.getKey());

        HashMap<String, String> combinedOverrideConfigs = Maps.newHashMap(overrideBuildSettings);
        for (Map.Entry<String, String> entry : defaultBuildSettings.entrySet()) {
            String existingSetting = targetLevelInlineSettings.get(entry.getKey());
            if (existingSetting == null) {
                combinedOverrideConfigs.put(entry.getKey(), entry.getValue());
            }
        }

        for (Map.Entry<String, String> entry : appendBuildSettings.entrySet()) {
            String existingSetting = targetLevelInlineSettings.get(entry.getKey());
            String settingPrefix = existingSetting != null ? existingSetting : "$(inherited)";
            combinedOverrideConfigs.put(entry.getKey(), settingPrefix + " " + entry.getValue());
        }

        ImmutableSortedMap<String, String> mergedSettings = MoreMaps.mergeSorted(targetLevelInlineSettings,
                combinedOverrideConfigs);
        Path xcconfigPath = configurationNameToXcconfigPath.apply(configurationEntry.getKey());
        projectFilesystem.mkdirs(Preconditions.checkNotNull(xcconfigPath).getParent());

        StringBuilder stringBuilder = new StringBuilder();
        for (Map.Entry<String, String> entry : mergedSettings.entrySet()) {
            stringBuilder.append(entry.getKey());
            stringBuilder.append(" = ");
            stringBuilder.append(entry.getValue());
            stringBuilder.append('\n');
        }
        String xcconfigContents = stringBuilder.toString();

        if (MoreProjectFilesystems.fileContentsDiffer(
                new ByteArrayInputStream(xcconfigContents.getBytes(Charsets.UTF_8)), xcconfigPath,
                projectFilesystem)) {
            if (shouldGenerateReadOnlyFiles()) {
                projectFilesystem.writeContentsToPath(xcconfigContents, xcconfigPath, READ_ONLY_FILE_ATTRIBUTE);
            } else {
                projectFilesystem.writeContentsToPath(xcconfigContents, xcconfigPath);
            }
        }

        PBXFileReference fileReference = getConfigurationFileReference(targetGroup, xcconfigPath);
        outputConfiguration.setBaseConfigurationReference(fileReference);
    }
}

From source file:com.facebook.buck.apple.xcode.ProjectGenerator.java

/**
 * Create project level (if it does not exist) and target level configuration entries.
 *
 * Each configuration should have an empty entry at the project level. The target level entries
 * combine the configuration values of every layer into a single configuration file that is
 * effectively laid out in layers./*from   w ww.j a v  a 2s  .c om*/
 */
private void setTargetBuildConfigurations(BuildTarget buildTarget, PBXTarget target, PBXGroup targetGroup,
        ImmutableSet<XcodeRuleConfiguration> configurations, ImmutableMap<String, String> extraBuildSettings)
        throws IOException {

    ImmutableMap.Builder<String, String> extraConfigsBuilder = ImmutableMap.builder();

    extraConfigsBuilder.putAll(extraBuildSettings).put("TARGET_NAME", getProductName(buildTarget))
            .put("SRCROOT", relativizeBuckRelativePathToGeneratedProject(buildTarget, "").toString());

    // HACK: GCC_PREFIX_HEADER needs to be modified because the path is referenced relative to
    // project root, so if the project is generated in a different place from the BUCK file, it
    // would break. This forces it to be based off of SRCROOT, which is overriden to point to the
    // BUCK file location.
    // However, when using REFERENCE_EXISTING_XCCONFIGS, this setting is not put into another layer,
    // and therefore may override an existing setting in the target-inline-config level.
    // Fortunately, this option is only set when we are generating separated projects, which are
    // placed next to the BUCK files, so avoiding this is OK.
    // In the long run, setting should be written relative to SRCROOT everywhere, and this entire
    // hack can be deleted.
    if (!options.contains(Option.REFERENCE_EXISTING_XCCONFIGS)) {
        extraConfigsBuilder.put("GCC_PREFIX_HEADER", "$(SRCROOT)/$(inherited)");
    }

    ImmutableMap<String, String> extraConfigs = extraConfigsBuilder.build();

    PBXGroup configurationsGroup = targetGroup.getOrCreateChildGroupByName("Configurations");

    for (XcodeRuleConfiguration configuration : configurations) {
        if (options.contains(Option.REFERENCE_EXISTING_XCCONFIGS)) {
            ConfigInXcodeLayout layers = extractXcodeConfigurationLayers(buildTarget, configuration);
            xcodeConfigurationLayersMultimapBuilder.put(configuration.getName(), layers);

            XCBuildConfiguration outputConfiguration = target.getBuildConfigurationList()
                    .getBuildConfigurationsByName().getUnchecked(configuration.getName());
            if (layers.targetLevelConfigFile.isPresent()) {
                PBXFileReference fileReference = configurationsGroup.getOrCreateFileReferenceBySourceTreePath(
                        new SourceTreePath(PBXReference.SourceTree.SOURCE_ROOT,
                                this.repoRootRelativeToOutputDirectory
                                        .resolve(layers.targetLevelConfigFile.get()).normalize()));
                outputConfiguration.setBaseConfigurationReference(fileReference);

                NSDictionary inlineSettings = new NSDictionary();
                Iterable<Map.Entry<String, String>> entries = Iterables
                        .concat(layers.targetLevelInlineSettings.entrySet(), extraConfigs.entrySet());
                for (Map.Entry<String, String> entry : entries) {
                    inlineSettings.put(entry.getKey(), entry.getValue());
                }
                outputConfiguration.setBuildSettings(inlineSettings);
            }
        } else {
            Path outputConfigurationDirectory = outputDirectory.resolve("Configurations");
            projectFilesystem.mkdirs(outputConfigurationDirectory);

            Path originalProjectPath = projectFilesystem
                    .getPathForRelativePath(Paths.get(buildTarget.getBasePathWithSlash()));

            // XCConfig search path is relative to the xcode project and the file itself.
            ImmutableList<Path> searchPaths = ImmutableList.of(originalProjectPath);

            // Call for effect to create a stub configuration entry at project level.
            project.getBuildConfigurationList().getBuildConfigurationsByName()
                    .getUnchecked(configuration.getName());

            // Write an xcconfig that embodies all the config levels, and set that as the target config.
            Path configurationFilePath = outputConfigurationDirectory
                    .resolve(mangledBuildTargetName(buildTarget) + "-" + configuration.getName() + ".xcconfig");
            String serializedConfiguration = serializeBuildConfiguration(configuration, searchPaths,
                    extraConfigs);
            projectFilesystem.writeContentsToPath(serializedConfiguration, configurationFilePath);

            PBXFileReference fileReference = configurationsGroup.getOrCreateFileReferenceBySourceTreePath(
                    new SourceTreePath(PBXReference.SourceTree.SOURCE_ROOT,
                            this.repoRootRelativeToOutputDirectory.resolve(configurationFilePath)));
            XCBuildConfiguration outputConfiguration = target.getBuildConfigurationList()
                    .getBuildConfigurationsByName().getUnchecked(configuration.getName());
            outputConfiguration.setBaseConfigurationReference(fileReference);
        }
    }
}

From source file:com.google.devtools.build.lib.skyframe.SkyframeBuildView.java

/**
 * Analyzes the specified targets using Skyframe as the driving framework.
 *
 * @return the configured targets that should be built along with a WalkableGraph of the analysis.
 *///  ww w . ja  va 2 s  .co m
public SkyframeAnalysisResult configureTargets(EventHandler eventHandler, List<ConfiguredTargetKey> values,
        List<AspectValueKey> aspectKeys, EventBus eventBus, boolean keepGoing, int numThreads)
        throws InterruptedException, ViewCreationFailedException {
    enableAnalysis(true);
    EvaluationResult<ActionLookupValue> result;
    try {
        result = skyframeExecutor.configureTargets(eventHandler, values, aspectKeys, keepGoing, numThreads);
    } finally {
        enableAnalysis(false);
    }
    ImmutableMap<ActionAnalysisMetadata, ConflictException> badActions = skyframeExecutor
            .findArtifactConflicts();

    Collection<AspectValue> goodAspects = Lists.newArrayListWithCapacity(values.size());
    NestedSetBuilder<Package> packages = NestedSetBuilder.stableOrder();
    for (AspectValueKey aspectKey : aspectKeys) {
        AspectValue value = (AspectValue) result.get(aspectKey.getSkyKey());
        if (value == null) {
            // Skip aspects that couldn't be applied to targets.
            continue;
        }
        goodAspects.add(value);
        packages.addTransitive(value.getTransitivePackages());
    }

    // Filter out all CTs that have a bad action and convert to a list of configured targets. This
    // code ensures that the resulting list of configured targets has the same order as the incoming
    // list of values, i.e., that the order is deterministic.
    Collection<ConfiguredTarget> goodCts = Lists.newArrayListWithCapacity(values.size());
    for (ConfiguredTargetKey value : values) {
        ConfiguredTargetValue ctValue = (ConfiguredTargetValue) result.get(ConfiguredTargetValue.key(value));
        if (ctValue == null) {
            continue;
        }
        goodCts.add(ctValue.getConfiguredTarget());
        packages.addTransitive(ctValue.getTransitivePackages());
    }
    ImmutableMap<PackageIdentifier, Path> packageRoots = LoadingPhaseRunner
            .collectPackageRoots(packages.build().toCollection());

    if (!result.hasError() && badActions.isEmpty()) {
        return new SkyframeAnalysisResult(/*hasLoadingError=*/false, /*hasAnalysisError=*/false,
                ImmutableList.copyOf(goodCts), result.getWalkableGraph(), ImmutableList.copyOf(goodAspects),
                packageRoots);
    }

    // --nokeep_going so we fail with an exception for the first error.
    // TODO(bazel-team): We might want to report the other errors through the event bus but
    // for keeping this code in parity with legacy we just report the first error for now.
    if (!keepGoing) {
        for (Map.Entry<ActionAnalysisMetadata, ConflictException> bad : badActions.entrySet()) {
            ConflictException ex = bad.getValue();
            try {
                ex.rethrowTyped();
            } catch (MutableActionGraph.ActionConflictException ace) {
                ace.reportTo(eventHandler);
                String errorMsg = "Analysis of target '" + bad.getKey().getOwner().getLabel()
                        + "' failed; build aborted";
                throw new ViewCreationFailedException(errorMsg);
            } catch (ArtifactPrefixConflictException apce) {
                eventHandler.handle(Event.error(apce.getMessage()));
            }
            throw new ViewCreationFailedException(ex.getMessage());
        }

        Map.Entry<SkyKey, ErrorInfo> error = result.errorMap().entrySet().iterator().next();
        SkyKey topLevel = error.getKey();
        ErrorInfo errorInfo = error.getValue();
        assertSaneAnalysisError(errorInfo, topLevel);
        skyframeExecutor.getCyclesReporter().reportCycles(errorInfo.getCycleInfo(), topLevel, eventHandler);
        Throwable cause = errorInfo.getException();
        Preconditions.checkState(cause != null || !Iterables.isEmpty(errorInfo.getCycleInfo()), errorInfo);
        String errorMsg = null;
        if (topLevel.argument() instanceof ConfiguredTargetKey) {
            errorMsg = "Analysis of target '" + ConfiguredTargetValue.extractLabel(topLevel)
                    + "' failed; build aborted";
        } else if (topLevel.argument() instanceof AspectValueKey) {
            AspectValueKey aspectKey = (AspectValueKey) topLevel.argument();
            errorMsg = "Analysis of aspect '" + aspectKey.getDescription() + "' failed; build aborted";
        } else {
            assert false;
        }
        if (cause instanceof ActionConflictException) {
            ((ActionConflictException) cause).reportTo(eventHandler);
        }
        throw new ViewCreationFailedException(errorMsg);
    }

    boolean hasLoadingError = false;
    // --keep_going : We notify the error and return a ConfiguredTargetValue
    for (Map.Entry<SkyKey, ErrorInfo> errorEntry : result.errorMap().entrySet()) {
        // Only handle errors of configured targets, not errors of top-level aspects.
        // TODO(ulfjack): this is quadratic - if there are a lot of CTs, this could be rather slow.
        if (!values.contains(errorEntry.getKey().argument())) {
            continue;
        }
        SkyKey errorKey = errorEntry.getKey();
        ConfiguredTargetKey label = (ConfiguredTargetKey) errorKey.argument();
        Label topLevelLabel = label.getLabel();
        ErrorInfo errorInfo = errorEntry.getValue();
        assertSaneAnalysisError(errorInfo, errorKey);

        skyframeExecutor.getCyclesReporter().reportCycles(errorInfo.getCycleInfo(), errorKey, eventHandler);
        Exception cause = errorInfo.getException();
        Label analysisRootCause = null;
        if (cause instanceof ConfiguredValueCreationException) {
            ConfiguredValueCreationException ctCause = (ConfiguredValueCreationException) cause;
            for (Label rootCause : ctCause.getRootCauses()) {
                hasLoadingError = true;
                eventBus.post(new LoadingFailureEvent(topLevelLabel, rootCause));
            }
            analysisRootCause = ctCause.getAnalysisRootCause();
        } else if (!Iterables.isEmpty(errorInfo.getCycleInfo())) {
            analysisRootCause = maybeGetConfiguredTargetCycleCulprit(topLevelLabel, errorInfo.getCycleInfo());
        } else if (cause instanceof ActionConflictException) {
            ((ActionConflictException) cause).reportTo(eventHandler);
        }
        eventHandler.handle(Event.warn(
                "errors encountered while analyzing target '" + topLevelLabel + "': it will not be built"));
        if (analysisRootCause != null) {
            eventBus.post(new AnalysisFailureEvent(
                    LabelAndConfiguration.of(topLevelLabel, label.getConfiguration()), analysisRootCause));
        }
    }

    Collection<Exception> reportedExceptions = Sets.newHashSet();
    for (Map.Entry<ActionAnalysisMetadata, ConflictException> bad : badActions.entrySet()) {
        ConflictException ex = bad.getValue();
        try {
            ex.rethrowTyped();
        } catch (MutableActionGraph.ActionConflictException ace) {
            ace.reportTo(eventHandler);
            eventHandler.handle(Event.warn("errors encountered while analyzing target '"
                    + bad.getKey().getOwner().getLabel() + "': it will not be built"));
        } catch (ArtifactPrefixConflictException apce) {
            if (reportedExceptions.add(apce)) {
                eventHandler.handle(Event.error(apce.getMessage()));
            }
        }
    }

    if (!badActions.isEmpty()) {
        // In order to determine the set of configured targets transitively error free from action
        // conflict issues, we run a post-processing update() that uses the bad action map.
        EvaluationResult<PostConfiguredTargetValue> actionConflictResult = skyframeExecutor
                .postConfigureTargets(eventHandler, values, keepGoing, badActions);

        goodCts = Lists.newArrayListWithCapacity(values.size());
        for (ConfiguredTargetKey value : values) {
            PostConfiguredTargetValue postCt = actionConflictResult.get(PostConfiguredTargetValue.key(value));
            if (postCt != null) {
                goodCts.add(postCt.getCt());
            }
        }
    }

    return new SkyframeAnalysisResult(hasLoadingError, result.hasError() || !badActions.isEmpty(),
            ImmutableList.copyOf(goodCts), result.getWalkableGraph(), ImmutableList.copyOf(goodAspects),
            packageRoots);
}

From source file:dagger2.internal.codegen.ComponentGenerator.java

/**
 * Writes out a builder for a component or subcomponent.
 *
 * @param input the component or subcomponent
 * @param componentApiName the API name of the component we're building (not our impl)
 * @param componentImplName the implementation name of the component we're building
 * @param componentWriter the class we're adding this builder to
 * @param componentContributionFields a map of member selects so we can later use the fields
 *//*from w w  w .  j av  a 2s .c o m*/
private ClassWriter writeBuilder(BindingGraph input, ClassName componentApiName, ClassName componentImplName,
        ClassWriter componentWriter, Map<TypeElement, MemberSelect> componentContributionFields) {
    ClassWriter builderWriter;
    Optional<BuilderSpec> builderSpec = input.componentDescriptor().builderSpec();
    switch (input.componentDescriptor().kind()) {
    case COMPONENT:
    case PRODUCTION_COMPONENT:
        builderWriter = componentWriter.addNestedClass("Builder");
        builderWriter.addModifiers(STATIC);

        // Only top-level components have the factory builder() method.
        // Mirror the user's builder API type if they had one.
        MethodWriter builderFactoryMethod = builderSpec.isPresent()
                ? componentWriter.addMethod(builderSpec.get().builderDefinitionType().asType(), "builder")
                : componentWriter.addMethod(builderWriter, "builder");
        builderFactoryMethod.addModifiers(PUBLIC, STATIC);
        builderFactoryMethod.body().addSnippet("return new %s();", builderWriter.name());
        break;
    case SUBCOMPONENT:
        verify(builderSpec.isPresent()); // we only write subcomponent builders if there was a spec
        builderWriter = componentWriter.addNestedClass(componentApiName.simpleName() + "Builder");
        break;
    default:
        throw new IllegalStateException();
    }
    builderWriter.addModifiers(FINAL);
    builderWriter.addConstructor().addModifiers(PRIVATE);
    if (builderSpec.isPresent()) {
        builderWriter.addModifiers(PRIVATE);
        TypeElement builderType = builderSpec.get().builderDefinitionType();
        switch (builderType.getKind()) {
        case CLASS:
            builderWriter.setSuperType(builderType);
            break;
        case INTERFACE:
            builderWriter.addImplementedType(builderType);
            break;
        default:
            throw new IllegalStateException("not a class or interface: " + builderType);
        }
    } else {
        builderWriter.addModifiers(PUBLIC);
    }

    // the full set of types that calling code uses to construct a component instance
    ImmutableMap<TypeElement, String> componentContributionNames = ImmutableMap
            .copyOf(Maps.asMap(
                    Sets.union(
                            Sets.union(input.transitiveModules().keySet(),
                                    input.componentDescriptor().dependencies()),
                            input.componentDescriptor().executorDependency().asSet()),
                    Functions.compose(CaseFormat.UPPER_CAMEL.converterTo(LOWER_CAMEL),
                            new Function<TypeElement, String>() {
                                @Override
                                public String apply(TypeElement input) {
                                    return input.getSimpleName().toString();
                                }
                            })));

    MethodWriter buildMethod;
    if (builderSpec.isPresent()) {
        ExecutableElement specBuildMethod = builderSpec.get().buildMethod();
        // Note: we don't use the specBuildMethod.getReturnType() as the return type
        // because it might be a type variable.  We make use of covariant returns to allow
        // us to return the component type, which will always be valid.
        buildMethod = builderWriter.addMethod(componentApiName, specBuildMethod.getSimpleName().toString());
        buildMethod.annotate(Override.class);
    } else {
        buildMethod = builderWriter.addMethod(componentApiName, "build");
    }
    buildMethod.addModifiers(PUBLIC);

    for (Entry<TypeElement, String> entry : componentContributionNames.entrySet()) {
        TypeElement contributionElement = entry.getKey();
        String contributionName = entry.getValue();
        FieldWriter builderField = builderWriter.addField(contributionElement, contributionName);
        builderField.addModifiers(PRIVATE);
        componentContributionFields.put(contributionElement, MemberSelect.instanceSelect(componentImplName,
                Snippet.format("builder.%s", builderField.name())));
        if (componentCanMakeNewInstances(contributionElement)) {
            buildMethod.body().addSnippet("if (%s == null) {", builderField.name())
                    .addSnippet("  this.%s = new %s();", builderField.name(),
                            ClassName.fromTypeElement(contributionElement))
                    .addSnippet("}");
        } else {
            buildMethod.body().addSnippet("if (%s == null) {", builderField.name())
                    .addSnippet("  throw new IllegalStateException(\"%s must be set\");", builderField.name())
                    .addSnippet("}");
        }
        MethodWriter builderMethod;
        boolean returnsVoid = false;
        if (builderSpec.isPresent()) {
            ExecutableElement method = builderSpec.get().methodMap().get(contributionElement);
            if (method == null) { // no method in the API, nothing to write out.
                continue;
            }
            // If the return type is void, we add a method with the void return type.
            // Otherwise we use the builderWriter and take advantage of covariant returns
            // (so that we don't have to worry about setter methods that return type variables).
            if (method.getReturnType().getKind().equals(TypeKind.VOID)) {
                returnsVoid = true;
                builderMethod = builderWriter.addMethod(method.getReturnType(),
                        method.getSimpleName().toString());
            } else {
                builderMethod = builderWriter.addMethod(builderWriter, method.getSimpleName().toString());
            }
            builderMethod.annotate(Override.class);
        } else {
            builderMethod = builderWriter.addMethod(builderWriter, contributionName);
        }
        // TODO(gak): Mirror the API's visibility.
        // (Makes no difference to the user since this class is private,
        //  but makes generated code prettier.)
        builderMethod.addModifiers(PUBLIC);
        builderMethod.addParameter(contributionElement, contributionName);
        builderMethod.body().addSnippet("if (%s == null) {", contributionName)
                .addSnippet("  throw new NullPointerException(%s);", StringLiteral.forValue(contributionName))
                .addSnippet("}").addSnippet("this.%s = %s;", builderField.name(), contributionName);
        if (!returnsVoid) {
            builderMethod.body().addSnippet("return this;");
        }
    }
    buildMethod.body().addSnippet("return new %s(this);", componentImplName);
    return builderWriter;
}

From source file:com.google.devtools.build.lib.skyframe.SkylarkImportLookupFunction.java

private SkyValue computeInternal(Label fileLabel, boolean inWorkspace, Environment env,
        @Nullable LinkedHashMap<Label, SkylarkImportLookupValue> alreadyVisited)
        throws InconsistentFilesystemException, SkylarkImportFailedException, InterruptedException {
    PathFragment filePath = fileLabel.toPathFragment();

    // Load the AST corresponding to this file.
    ASTFileLookupValue astLookupValue;/*www  .  j ava 2  s  .c o  m*/
    try {
        SkyKey astLookupKey = ASTFileLookupValue.key(fileLabel);
        astLookupValue = (ASTFileLookupValue) env.getValueOrThrow(astLookupKey,
                ErrorReadingSkylarkExtensionException.class, InconsistentFilesystemException.class);
    } catch (ErrorReadingSkylarkExtensionException e) {
        throw SkylarkImportFailedException.errorReadingFile(filePath, e.getMessage());
    }
    if (astLookupValue == null) {
        return null;
    }
    if (!astLookupValue.lookupSuccessful()) {
        // Skylark import files have to exist.
        throw SkylarkImportFailedException.noFile(astLookupValue.getErrorMsg());
    }
    BuildFileAST ast = astLookupValue.getAST();
    if (ast.containsErrors()) {
        throw SkylarkImportFailedException.skylarkErrors(filePath);
    }

    // Process the load statements in the file.
    ImmutableList<SkylarkImport> imports = ast.getImports();
    Map<String, Extension> extensionsForImports = Maps.newHashMapWithExpectedSize(imports.size());
    ImmutableList.Builder<SkylarkFileDependency> fileDependencies = ImmutableList.builder();
    ImmutableMap<String, Label> labelsForImports;

    // Find the labels corresponding to the load statements.
    labelsForImports = findLabelsForLoadStatements(imports, fileLabel, env);
    if (labelsForImports == null) {
        return null;
    }

    // Look up and load the imports.
    ImmutableCollection<Label> importLabels = labelsForImports.values();
    List<SkyKey> importLookupKeys = Lists.newArrayListWithExpectedSize(importLabels.size());
    for (Label importLabel : importLabels) {
        importLookupKeys.add(SkylarkImportLookupValue.key(importLabel, inWorkspace));
    }
    Map<SkyKey, SkyValue> skylarkImportMap;
    boolean valuesMissing = false;
    if (alreadyVisited == null) {
        // Not inlining.
        skylarkImportMap = env.getValues(importLookupKeys);
        valuesMissing = env.valuesMissing();
    } else {
        // Inlining calls to SkylarkImportLookupFunction.
        if (alreadyVisited.containsKey(fileLabel)) {
            ImmutableList<Label> cycle = CycleUtils.splitIntoPathAndChain(Predicates.equalTo(fileLabel),
                    alreadyVisited.keySet()).second;
            throw new SkylarkImportFailedException("Skylark import cycle: " + cycle);
        }
        alreadyVisited.put(fileLabel, null);
        skylarkImportMap = Maps.newHashMapWithExpectedSize(imports.size());
        for (SkyKey importLookupKey : importLookupKeys) {
            SkyValue skyValue = this.computeWithInlineCallsInternal(importLookupKey, env, alreadyVisited);
            if (skyValue == null) {
                Preconditions.checkState(env.valuesMissing(), "no skylark import value for %s",
                        importLookupKey);
                // We continue making inline calls even if some requested values are missing, to maximize
                // the number of dependent (non-inlined) SkyFunctions that are requested, thus avoiding a
                // quadratic number of restarts.
                valuesMissing = true;
            } else {
                skylarkImportMap.put(importLookupKey, skyValue);
            }
        }
        // All imports traversed, this key can no longer be part of a cycle.
        Preconditions.checkState(alreadyVisited.remove(fileLabel) == null, fileLabel);
    }
    if (valuesMissing) {
        // This means some imports are unavailable.
        return null;
    }

    // Process the loaded imports.
    for (Entry<String, Label> importEntry : labelsForImports.entrySet()) {
        String importString = importEntry.getKey();
        Label importLabel = importEntry.getValue();
        SkyKey keyForLabel = SkylarkImportLookupValue.key(importLabel, inWorkspace);
        SkylarkImportLookupValue importLookupValue = (SkylarkImportLookupValue) skylarkImportMap
                .get(keyForLabel);
        extensionsForImports.put(importString, importLookupValue.getEnvironmentExtension());
        fileDependencies.add(importLookupValue.getDependency());
    }

    // Skylark UserDefinedFunction-s in that file will share this function definition Environment,
    // which will be frozen by the time it is returned by createExtension.
    Extension extension = createExtension(ast, fileLabel, extensionsForImports, env, inWorkspace);
    SkylarkImportLookupValue result = new SkylarkImportLookupValue(extension,
            new SkylarkFileDependency(fileLabel, fileDependencies.build()));
    if (alreadyVisited != null) {
        alreadyVisited.put(fileLabel, result);
    }
    return result;
}

From source file:org.elasticsearch.action.admin.cluster.snapshots.status.TransportSnapshotsStatusAction.java

private SnapshotsStatusResponse buildResponse(SnapshotsStatusRequest request,
        ImmutableList<SnapshotMetaData.Entry> currentSnapshots,
        TransportNodesSnapshotsStatus.NodesSnapshotStatus nodeSnapshotStatuses) {
    // First process snapshot that are currently processed
    ImmutableList.Builder<SnapshotStatus> builder = ImmutableList.builder();
    Set<SnapshotId> currentSnapshotIds = newHashSet();
    if (!currentSnapshots.isEmpty()) {
        Map<String, TransportNodesSnapshotsStatus.NodeSnapshotStatus> nodeSnapshotStatusMap;
        if (nodeSnapshotStatuses != null) {
            nodeSnapshotStatusMap = nodeSnapshotStatuses.getNodesMap();
        } else {//  ww w.ja  v  a 2s  .c  o m
            nodeSnapshotStatusMap = newHashMap();
        }

        for (SnapshotMetaData.Entry entry : currentSnapshots) {
            currentSnapshotIds.add(entry.snapshotId());
            ImmutableList.Builder<SnapshotIndexShardStatus> shardStatusBuilder = ImmutableList.builder();
            for (ImmutableMap.Entry<ShardId, SnapshotMetaData.ShardSnapshotStatus> shardEntry : entry.shards()
                    .entrySet()) {
                SnapshotMetaData.ShardSnapshotStatus status = shardEntry.getValue();
                if (status.nodeId() != null) {
                    // We should have information about this shard from the shard:
                    TransportNodesSnapshotsStatus.NodeSnapshotStatus nodeStatus = nodeSnapshotStatusMap
                            .get(status.nodeId());
                    if (nodeStatus != null) {
                        ImmutableMap<ShardId, SnapshotIndexShardStatus> shardStatues = nodeStatus.status()
                                .get(entry.snapshotId());
                        if (shardStatues != null) {
                            SnapshotIndexShardStatus shardStatus = shardStatues.get(shardEntry.getKey());
                            if (shardStatus != null) {
                                // We have full information about this shard
                                shardStatusBuilder.add(shardStatus);
                                continue;
                            }
                        }
                    }
                }
                final SnapshotIndexShardStage stage;
                switch (shardEntry.getValue().state()) {
                case FAILED:
                case ABORTED:
                case MISSING:
                    stage = SnapshotIndexShardStage.FAILURE;
                    break;
                case INIT:
                case WAITING:
                case STARTED:
                    stage = SnapshotIndexShardStage.STARTED;
                    break;
                case SUCCESS:
                    stage = SnapshotIndexShardStage.DONE;
                    break;
                default:
                    throw new ElasticsearchIllegalArgumentException(
                            "Unknown snapshot state " + shardEntry.getValue().state());
                }
                SnapshotIndexShardStatus shardStatus = new SnapshotIndexShardStatus(
                        shardEntry.getKey().getIndex(), shardEntry.getKey().getId(), stage);
                shardStatusBuilder.add(shardStatus);
            }
            builder.add(new SnapshotStatus(entry.snapshotId(), entry.state(), shardStatusBuilder.build()));
        }
    }
    // Now add snapshots on disk that are not currently running
    if (Strings.hasText(request.repository())) {
        if (request.snapshots() != null && request.snapshots().length > 0) {
            for (String snapshotName : request.snapshots()) {
                SnapshotId snapshotId = new SnapshotId(request.repository(), snapshotName);
                if (currentSnapshotIds.contains(snapshotId)) {
                    // This is a snapshot the is currently running - skipping
                    continue;
                }
                Snapshot snapshot = snapshotsService.snapshot(snapshotId);
                ImmutableList.Builder<SnapshotIndexShardStatus> shardStatusBuilder = ImmutableList.builder();
                if (snapshot.state().completed()) {
                    ImmutableMap<ShardId, IndexShardSnapshotStatus> shardStatues = snapshotsService
                            .snapshotShards(snapshotId);
                    for (ImmutableMap.Entry<ShardId, IndexShardSnapshotStatus> shardStatus : shardStatues
                            .entrySet()) {
                        shardStatusBuilder.add(
                                new SnapshotIndexShardStatus(shardStatus.getKey(), shardStatus.getValue()));
                    }
                    final SnapshotMetaData.State state;
                    switch (snapshot.state()) {
                    case FAILED:
                        state = SnapshotMetaData.State.FAILED;
                        break;
                    case SUCCESS:
                    case PARTIAL:
                        // Translating both PARTIAL and SUCCESS to SUCCESS for now
                        // TODO: add the differentiation on the metadata level in the next major release
                        state = SnapshotMetaData.State.SUCCESS;
                        break;
                    default:
                        throw new ElasticsearchIllegalArgumentException(
                                "Unknown snapshot state " + snapshot.state());
                    }
                    builder.add(new SnapshotStatus(snapshotId, state, shardStatusBuilder.build()));
                }
            }
        }
    }

    return new SnapshotsStatusResponse(builder.build());
}

From source file:com.facebook.buck.features.apple.project.ProjectGenerator.java

/** Adds the set of headers defined by headerVisibility to the merged header maps. */
private void addToMergedHeaderMap(TargetNode<? extends CxxLibraryDescription.CommonArg> targetNode,
        HeaderMap.Builder headerMapBuilder) {
    CxxLibraryDescription.CommonArg arg = targetNode.getConstructorArg();
    boolean shouldCreateHeadersSymlinks = arg.getXcodePublicHeadersSymlinks()
            .orElse(cxxBuckConfig.getPublicHeadersSymlinksEnabled());
    Path headerSymlinkTreeRoot = getPathToHeaderSymlinkTree(targetNode, HeaderVisibility.PUBLIC);

    Path basePath;//from  w  w w  .  j a  v a2s  . com
    if (shouldCreateHeadersSymlinks) {
        basePath = projectFilesystem.getRootPath().resolve(targetNode.getBuildTarget().getCellPath())
                .resolve(headerSymlinkTreeRoot);
    } else {
        basePath = projectFilesystem.getRootPath();
    }
    for (Map.Entry<Path, SourcePath> entry : getPublicCxxHeaders(targetNode).entrySet()) {
        Path path;
        if (shouldCreateHeadersSymlinks) {
            path = basePath.resolve(entry.getKey());
        } else {
            path = basePath.resolve(resolveSourcePath(entry.getValue()));
        }
        headerMapBuilder.add(entry.getKey().toString(), path);
    }

    ImmutableMap<Path, Path> swiftHeaderMapEntries = getSwiftPublicHeaderMapEntriesForTarget(targetNode);
    for (Map.Entry<Path, Path> entry : swiftHeaderMapEntries.entrySet()) {
        headerMapBuilder.add(entry.getKey().toString(), entry.getValue());
    }
}

From source file:com.google.devtools.build.lib.skyframe.PackageFunction.java

/**
 * Fetch the skylark loads for this BUILD file. If any of them haven't been computed yet,
 * returns null./*from  w  w  w  . j a  v  a 2  s .  c  o m*/
 */
@Nullable
static SkylarkImportResult fetchImportsFromBuildFile(Path buildFilePath, PackageIdentifier packageId,
        BuildFileAST buildFileAST, Environment env,
        SkylarkImportLookupFunction skylarkImportLookupFunctionForInlining)
        throws PackageFunctionException, InterruptedException {
    Preconditions.checkArgument(!packageId.getRepository().isDefault());

    ImmutableList<SkylarkImport> imports = buildFileAST.getImports();
    Map<String, Extension> importMap = Maps.newHashMapWithExpectedSize(imports.size());
    ImmutableList.Builder<SkylarkFileDependency> fileDependencies = ImmutableList.builder();
    ImmutableMap<String, Label> importPathMap;

    // Find the labels corresponding to the load statements.
    Label labelForCurrBuildFile;
    try {
        labelForCurrBuildFile = Label.create(packageId, "BUILD");
    } catch (LabelSyntaxException e) {
        // Shouldn't happen; the Label is well-formed by construction.
        throw new IllegalStateException(e);
    }
    try {
        importPathMap = SkylarkImportLookupFunction.findLabelsForLoadStatements(imports, labelForCurrBuildFile,
                env);
        if (importPathMap == null) {
            return null;
        }
    } catch (SkylarkImportFailedException e) {
        throw new PackageFunctionException(new BuildFileContainsErrorsException(packageId, e.getMessage()),
                Transience.PERSISTENT);
    }

    // Look up and load the imports.
    ImmutableCollection<Label> importLabels = importPathMap.values();
    List<SkyKey> importLookupKeys = Lists.newArrayListWithExpectedSize(importLabels.size());
    boolean inWorkspace = buildFilePath.getBaseName().endsWith("WORKSPACE");
    for (Label importLabel : importLabels) {
        importLookupKeys.add(SkylarkImportLookupValue.key(importLabel, inWorkspace));
    }
    Map<SkyKey, SkyValue> skylarkImportMap = Maps.newHashMapWithExpectedSize(importPathMap.size());
    boolean valuesMissing = false;

    try {
        if (skylarkImportLookupFunctionForInlining == null) {
            // Not inlining
            Map<SkyKey, ValueOrException2<SkylarkImportFailedException, InconsistentFilesystemException>> skylarkLookupResults = env
                    .getValuesOrThrow(importLookupKeys, SkylarkImportFailedException.class,
                            InconsistentFilesystemException.class);
            valuesMissing = env.valuesMissing();
            for (Map.Entry<SkyKey, ValueOrException2<SkylarkImportFailedException, InconsistentFilesystemException>> entry : skylarkLookupResults
                    .entrySet()) {
                // Fetching the value will raise any deferred exceptions
                skylarkImportMap.put(entry.getKey(), entry.getValue().get());
            }
        } else {
            // Inlining calls to SkylarkImportLookupFunction
            LinkedHashMap<Label, SkylarkImportLookupValue> alreadyVisitedImports = Maps
                    .newLinkedHashMapWithExpectedSize(importLookupKeys.size());
            for (SkyKey importLookupKey : importLookupKeys) {
                SkyValue skyValue = skylarkImportLookupFunctionForInlining
                        .computeWithInlineCalls(importLookupKey, env, alreadyVisitedImports);
                if (skyValue == null) {
                    Preconditions.checkState(env.valuesMissing(), "no skylark import value for %s",
                            importLookupKey);
                    // We continue making inline calls even if some requested values are missing, to
                    // maximize the number of dependent (non-inlined) SkyFunctions that are requested, thus
                    // avoiding a quadratic number of restarts.
                    valuesMissing = true;
                } else {
                    skylarkImportMap.put(importLookupKey, skyValue);
                }
            }

        }
    } catch (SkylarkImportFailedException e) {
        throw new PackageFunctionException(new BuildFileContainsErrorsException(packageId, e.getMessage()),
                Transience.PERSISTENT);
    } catch (InconsistentFilesystemException e) {
        throw new PackageFunctionException(new NoSuchPackageException(packageId, e.getMessage(), e),
                Transience.PERSISTENT);
    }

    if (valuesMissing) {
        // Some imports are unavailable.
        return null;
    }

    // Process the loaded imports.
    for (Entry<String, Label> importEntry : importPathMap.entrySet()) {
        String importString = importEntry.getKey();
        Label importLabel = importEntry.getValue();
        SkyKey keyForLabel = SkylarkImportLookupValue.key(importLabel, inWorkspace);
        SkylarkImportLookupValue importLookupValue = (SkylarkImportLookupValue) skylarkImportMap
                .get(keyForLabel);
        importMap.put(importString, importLookupValue.getEnvironmentExtension());
        fileDependencies.add(importLookupValue.getDependency());
    }

    return new SkylarkImportResult(importMap, transitiveClosureOfLabels(fileDependencies.build()));
}

From source file:com.facebook.buck.features.apple.project.ProjectGenerator.java

/**
 * Create target level configuration entries.
 *
 * @param target Xcode target for which the configurations will be set.
 * @param targetGroup Xcode group in which the configuration file references will be placed.
 * @param configurations Configurations as extracted from the BUCK file.
 * @param overrideBuildSettings Build settings that will override ones defined elsewhere.
 * @param defaultBuildSettings Target-inline level build settings that will be set if not already
 *     defined.//from  www .j  a  v a2s .c  o  m
 * @param appendBuildSettings Target-inline level build settings that will incorporate the
 *     existing value or values at a higher level.
 */
private void setTargetBuildConfigurations(BuildTarget buildTarget, PBXTarget target, PBXGroup targetGroup,
        ImmutableMap<String, ImmutableMap<String, String>> configurations,
        ImmutableMap<String, String> cxxPlatformXcodeBuildSettings,
        ImmutableMap<String, String> overrideBuildSettings, ImmutableMap<String, String> defaultBuildSettings,
        ImmutableMap<String, String> appendBuildSettings) throws IOException {
    if (options.shouldGenerateHeaderSymlinkTreesOnly()) {
        return;
    }

    for (Map.Entry<String, ImmutableMap<String, String>> configurationEntry : configurations.entrySet()) {
        targetConfigNamesBuilder.add(configurationEntry.getKey());

        ImmutableMap<String, String> targetLevelInlineSettings = configurationEntry.getValue();

        XCBuildConfiguration outputConfiguration = target.getBuildConfigurationList()
                .getBuildConfigurationsByName().getUnchecked(configurationEntry.getKey());

        HashMap<String, String> combinedOverrideConfigs = new HashMap<>(overrideBuildSettings);
        for (Map.Entry<String, String> entry : cxxPlatformXcodeBuildSettings.entrySet()) {
            String existingSetting = targetLevelInlineSettings.get(entry.getKey());
            if (existingSetting == null) {
                combinedOverrideConfigs.put(entry.getKey(), entry.getValue());
            }
        }

        for (Map.Entry<String, String> entry : defaultBuildSettings.entrySet()) {
            String existingSetting = targetLevelInlineSettings.get(entry.getKey());
            if (existingSetting == null) {
                combinedOverrideConfigs.put(entry.getKey(), entry.getValue());
            }
        }

        for (Map.Entry<String, String> entry : appendBuildSettings.entrySet()) {
            String existingSetting = targetLevelInlineSettings.get(entry.getKey());
            String settingPrefix = existingSetting != null ? existingSetting : "$(inherited)";
            combinedOverrideConfigs.put(entry.getKey(), settingPrefix + " " + entry.getValue());
        }

        ImmutableSortedMap<String, String> mergedSettings = MoreMaps.mergeSorted(targetLevelInlineSettings,
                combinedOverrideConfigs);
        Path xcconfigPath = getConfigurationXcconfigPath(buildTarget, configurationEntry.getKey());
        projectFilesystem.mkdirs(Objects.requireNonNull(xcconfigPath).getParent());

        StringBuilder stringBuilder = new StringBuilder();
        for (Map.Entry<String, String> entry : mergedSettings.entrySet()) {
            stringBuilder.append(entry.getKey());
            stringBuilder.append(" = ");
            stringBuilder.append(entry.getValue());
            stringBuilder.append('\n');
        }
        String xcconfigContents = stringBuilder.toString();

        if (MoreProjectFilesystems.fileContentsDiffer(
                new ByteArrayInputStream(xcconfigContents.getBytes(Charsets.UTF_8)), xcconfigPath,
                projectFilesystem)) {
            if (options.shouldGenerateReadOnlyFiles()) {
                projectFilesystem.writeContentsToPath(xcconfigContents, xcconfigPath, READ_ONLY_FILE_ATTRIBUTE);
            } else {
                projectFilesystem.writeContentsToPath(xcconfigContents, xcconfigPath);
            }
        }

        PBXFileReference fileReference = getConfigurationFileReference(targetGroup, xcconfigPath);
        outputConfiguration.setBaseConfigurationReference(fileReference);

        xcconfigPathsBuilder.add(projectFilesystem.getPathForRelativePath(xcconfigPath).toAbsolutePath());
    }
}

From source file:com.facebook.buck.features.apple.project.ProjectGenerator.java

private void createHeaderSymlinkTree(Map<Path, SourcePath> contents, ImmutableMap<Path, Path> nonSourcePaths,
        Optional<String> moduleName, Path headerSymlinkTreeRoot, boolean shouldCreateHeadersSymlinks,
        boolean shouldCreateHeaderMap, boolean shouldGenerateUmbrellaHeaderIfMissing) throws IOException {
    if (!shouldCreateHeaderMap && !shouldCreateHeadersSymlinks) {
        return;/*from  w w w.j  a  v a 2s .c  o  m*/
    }
    LOG.verbose("Building header symlink tree at %s with contents %s", headerSymlinkTreeRoot, contents);
    ImmutableSortedMap.Builder<Path, Path> resolvedContentsBuilder = ImmutableSortedMap.naturalOrder();
    for (Map.Entry<Path, SourcePath> entry : contents.entrySet()) {
        Path link = headerSymlinkTreeRoot.resolve(entry.getKey());
        Path existing = projectFilesystem.resolve(resolveSourcePath(entry.getValue()));
        resolvedContentsBuilder.put(link, existing);
    }
    for (Map.Entry<Path, Path> entry : nonSourcePaths.entrySet()) {
        Path link = headerSymlinkTreeRoot.resolve(entry.getKey());
        resolvedContentsBuilder.put(link, entry.getValue());
    }
    ImmutableSortedMap<Path, Path> resolvedContents = resolvedContentsBuilder.build();

    Path headerMapLocation = getHeaderMapLocationFromSymlinkTreeRoot(headerSymlinkTreeRoot);

    Path hashCodeFilePath = headerSymlinkTreeRoot.resolve(".contents-hash");
    Optional<String> currentHashCode = projectFilesystem.readFileIfItExists(hashCodeFilePath);
    String newHashCode = getHeaderSymlinkTreeHashCode(resolvedContents, moduleName, shouldCreateHeadersSymlinks,
            shouldCreateHeaderMap).toString();
    if (Optional.of(newHashCode).equals(currentHashCode)) {
        LOG.debug("Symlink tree at %s is up to date, not regenerating (key %s).", headerSymlinkTreeRoot,
                newHashCode);
    } else {
        LOG.debug("Updating symlink tree at %s (old key %s, new key %s).", headerSymlinkTreeRoot,
                currentHashCode, newHashCode);
        projectFilesystem.deleteRecursivelyIfExists(headerSymlinkTreeRoot);
        projectFilesystem.mkdirs(headerSymlinkTreeRoot);
        if (shouldCreateHeadersSymlinks) {
            for (Map.Entry<Path, Path> entry : resolvedContents.entrySet()) {
                Path link = entry.getKey();
                Path existing = entry.getValue();
                projectFilesystem.createParentDirs(link);
                projectFilesystem.createSymLink(link, existing, /* force */ false);
            }
        }
        projectFilesystem.writeContentsToPath(newHashCode, hashCodeFilePath);

        if (shouldCreateHeaderMap) {
            HeaderMap.Builder headerMapBuilder = new HeaderMap.Builder();
            for (Map.Entry<Path, SourcePath> entry : contents.entrySet()) {
                if (shouldCreateHeadersSymlinks) {
                    headerMapBuilder.add(entry.getKey().toString(),
                            getHeaderMapRelativeSymlinkPathForEntry(entry, headerSymlinkTreeRoot));
                } else {
                    headerMapBuilder.add(entry.getKey().toString(),
                            projectFilesystem.resolve(resolveSourcePath(entry.getValue())));
                }
            }

            for (Map.Entry<Path, Path> entry : nonSourcePaths.entrySet()) {
                if (shouldCreateHeadersSymlinks) {
                    headerMapBuilder.add(entry.getKey().toString(),
                            getHeaderMapRelativeSymlinkPathForEntry(entry, headerSymlinkTreeRoot));
                } else {
                    headerMapBuilder.add(entry.getKey().toString(), entry.getValue());
                }
            }

            projectFilesystem.writeBytesToPath(headerMapBuilder.build().getBytes(), headerMapLocation);
        }
        if (moduleName.isPresent() && resolvedContents.size() > 0) {
            if (shouldGenerateUmbrellaHeaderIfMissing) {
                writeUmbrellaHeaderIfNeeded(moduleName.get(), resolvedContents.keySet(), headerSymlinkTreeRoot);
            }
            boolean containsSwift = !nonSourcePaths.isEmpty();
            if (containsSwift) {
                projectFilesystem.writeContentsToPath(
                        new ModuleMap(moduleName.get(), ModuleMap.SwiftMode.INCLUDE_SWIFT_HEADER).render(),
                        headerSymlinkTreeRoot.resolve(moduleName.get()).resolve("module.modulemap"));
                projectFilesystem.writeContentsToPath(
                        new ModuleMap(moduleName.get(), ModuleMap.SwiftMode.EXCLUDE_SWIFT_HEADER).render(),
                        headerSymlinkTreeRoot.resolve(moduleName.get()).resolve("objc.modulemap"));

                Path absoluteModuleRoot = projectFilesystem.getRootPath()
                        .resolve(headerSymlinkTreeRoot.resolve(moduleName.get()));
                VFSOverlay vfsOverlay = new VFSOverlay(
                        ImmutableSortedMap.of(absoluteModuleRoot.resolve("module.modulemap"),
                                absoluteModuleRoot.resolve("objc.modulemap")));

                projectFilesystem.writeContentsToPath(vfsOverlay.render(),
                        getObjcModulemapVFSOverlayLocationFromSymlinkTreeRoot(headerSymlinkTreeRoot));
            } else {
                projectFilesystem.writeContentsToPath(
                        new ModuleMap(moduleName.get(), ModuleMap.SwiftMode.NO_SWIFT).render(),
                        headerSymlinkTreeRoot.resolve(moduleName.get()).resolve("module.modulemap"));
            }
            Path absoluteModuleRoot = projectFilesystem.getRootPath()
                    .resolve(headerSymlinkTreeRoot.resolve(moduleName.get()));
            VFSOverlay vfsOverlay = new VFSOverlay(
                    ImmutableSortedMap.of(absoluteModuleRoot.resolve("module.modulemap"),
                            absoluteModuleRoot.resolve("testing.modulemap")));

            projectFilesystem.writeContentsToPath(vfsOverlay.render(),
                    getTestingModulemapVFSOverlayLocationFromSymlinkTreeRoot(headerSymlinkTreeRoot));
            projectFilesystem.writeContentsToPath("", // empty modulemap to allow non-modular imports for testing
                    headerSymlinkTreeRoot.resolve(moduleName.get()).resolve("testing.modulemap"));
        }
    }
    headerSymlinkTrees.add(headerSymlinkTreeRoot);
}