com.facebook.buck.cxx.AbstractCxxHeaders.java Source code

Java tutorial

Introduction

Here is the source code for com.facebook.buck.cxx.AbstractCxxHeaders.java

Source

/*
 * Copyright 2014-present Facebook, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may
 * not use this file except in compliance with the License. You may obtain
 * a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations
 * under the License.
 */

package com.facebook.buck.cxx;

import com.facebook.buck.model.BuildTarget;
import com.facebook.buck.rules.RuleKeyAppendable;
import com.facebook.buck.rules.RuleKeyBuilder;
import com.facebook.buck.rules.SourcePath;
import com.facebook.buck.util.HumanReadableException;
import com.facebook.buck.util.immutables.BuckStyleImmutable;
import com.google.common.collect.ImmutableSortedSet;
import com.google.common.collect.Maps;

import org.immutables.value.Value;

import java.nio.file.Path;
import java.util.Map;

@Value.Immutable
@BuckStyleImmutable
abstract class AbstractCxxHeaders implements RuleKeyAppendable {

    /**
     * Maps the name of the header (e.g. the path used to include it in a C/C++ source) to the
     * real location of the header.
     */
    abstract Map<Path, SourcePath> getNameToPathMap();

    /**
     * Maps the full path of the header (e.g. the path to the header that appears in error messages)
     * to the real location of the header.
     */
    abstract Map<Path, SourcePath> getFullNameToPathMap();

    @Override
    public RuleKeyBuilder appendToRuleKey(RuleKeyBuilder builder) {
        for (Path path : ImmutableSortedSet.copyOf(getNameToPathMap().keySet())) {
            SourcePath source = getNameToPathMap().get(path);
            builder.setReflectively("include(" + path.toString() + ")", source);
        }

        return builder;
    }

    public static void addAllEntriesToIncludeMap(Map<Path, SourcePath> destination, Map<Path, SourcePath> source)
            throws ConflictingHeadersException {
        for (Map.Entry<Path, SourcePath> entry : source.entrySet()) {
            SourcePath original = destination.put(entry.getKey(), entry.getValue());
            if (original != null && !original.equals(entry.getValue())) {
                throw new ConflictingHeadersException(entry.getKey(), original, entry.getValue());
            }
        }
    }

    public static CxxHeaders concat(Iterable<CxxHeaders> headerGroup) throws ConflictingHeadersException {

        Map<Path, SourcePath> nameToPathMap = Maps.newLinkedHashMap();
        Map<Path, SourcePath> fullNameToPathMap = Maps.newLinkedHashMap();

        for (CxxHeaders headers : headerGroup) {
            addAllEntriesToIncludeMap(nameToPathMap, headers.getNameToPathMap());
            addAllEntriesToIncludeMap(fullNameToPathMap, headers.getFullNameToPathMap());
        }

        return CxxHeaders.builder().setNameToPathMap(nameToPathMap).setFullNameToPathMap(fullNameToPathMap).build();
    }

    @SuppressWarnings("serial")
    public static class ConflictingHeadersException extends Exception {
        public ConflictingHeadersException(Path key, SourcePath value1, SourcePath value2) {
            super(String.format("'%s' maps to both %s.", key, ImmutableSortedSet.of(value1, value2)));
        }

        public HumanReadableException getHumanReadableExceptionForBuildTarget(BuildTarget buildTarget) {
            return new HumanReadableException(this, "Target '%s' uses conflicting header file mappings. %s",
                    buildTarget, getMessage());
        }
    }

}