/*
* 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.rules.macros;
import com.facebook.buck.model.BuildTarget;
import com.facebook.buck.model.MacroException;
import com.facebook.buck.parser.BuildTargetParseException;
import com.facebook.buck.parser.BuildTargetParser;
import com.facebook.buck.parser.BuildTargetPatternParser;
import com.facebook.buck.rules.BuildRule;
import com.facebook.buck.rules.BuildRuleResolver;
import com.facebook.buck.rules.CellPathResolver;
import com.facebook.buck.rules.SourcePathResolver;
import com.facebook.buck.rules.SourcePathRuleFinder;
import com.google.common.collect.ImmutableCollection;
import com.google.common.collect.ImmutableList;
import java.util.Optional;
import javax.annotation.Nullable;
/**
* Abstract expander which resolves using a references to another {@link BuildRule}.
*
* <p>Matches either a relative or fully-qualified build target wrapped in <tt>$()</tt>, unless the
* <code>$</code> is preceded by a backslash.
*/
public abstract class BuildTargetMacroExpander<M extends BuildTargetMacro>
extends AbstractMacroExpander<M> {
protected abstract String expand(SourcePathResolver resolver, BuildRule rule)
throws MacroException;
protected BuildRule resolve(BuildRuleResolver resolver, M input) throws MacroException {
Optional<BuildRule> rule = resolver.getRuleOptional(input.getTarget());
if (!rule.isPresent()) {
throw new MacroException(String.format("no rule %s", input.getTarget()));
}
return rule.get();
}
BuildTarget parseBuildTarget(
BuildTarget target, CellPathResolver cellNames, ImmutableList<String> input)
throws MacroException {
if (input.size() != 1) {
throw new MacroException(String.format("expected a single argument: %s", input));
}
try {
return BuildTargetParser.INSTANCE.parse(
input.get(0), BuildTargetPatternParser.forBaseName(target.getBaseName()), cellNames);
} catch (BuildTargetParseException e) {
throw new MacroException(e.getMessage(), e);
}
}
@Override
public String expandFrom(
BuildTarget target, CellPathResolver cellNames, BuildRuleResolver resolver, M input)
throws MacroException {
SourcePathResolver pathResolver = new SourcePathResolver(new SourcePathRuleFinder(resolver));
return expand(pathResolver, resolve(resolver, input));
}
protected ImmutableList<BuildRule> extractBuildTimeDeps(
@SuppressWarnings("unused") BuildRuleResolver resolver, BuildRule rule)
throws MacroException {
return ImmutableList.of(rule);
}
@Override
public ImmutableList<BuildRule> extractBuildTimeDepsFrom(
BuildTarget target, CellPathResolver cellNames, BuildRuleResolver resolver, M input)
throws MacroException {
return extractBuildTimeDeps(resolver, resolve(resolver, input));
}
@Override
public void extractParseTimeDepsFrom(
BuildTarget target,
CellPathResolver cellNames,
M input,
ImmutableCollection.Builder<BuildTarget> buildDepsBuilder,
ImmutableCollection.Builder<BuildTarget> targetGraphOnlyDepsBuilder) {
buildDepsBuilder.add(input.getTarget());
}
@Override
@Nullable
public Object extractRuleKeyAppendablesFrom(
BuildTarget target, CellPathResolver cellNames, BuildRuleResolver resolver, M input)
throws MacroException {
return resolve(resolver, input).getSourcePathToOutput();
}
}