// Copyright 2014 The Bazel Authors. All rights reserved. // // 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.google.devtools.build.lib.rules.objc; import com.google.common.base.Objects; import com.google.common.collect.ImmutableList; import com.google.common.collect.Iterables; import com.google.common.collect.Iterators; import com.google.devtools.build.lib.actions.Artifact; import com.google.devtools.build.lib.analysis.RuleContext; import com.google.devtools.build.lib.cmdline.Label; import com.google.devtools.build.lib.vfs.FileSystemUtils; import com.google.devtools.build.lib.vfs.PathFragment; /** * An object that captures information of ObjC files generated by J2ObjC in a single target. */ public class J2ObjcSource { /** * Indicates the type of files from which the ObjC files included in {@link J2ObjcSource} are * generated. */ public enum SourceType { /** * Indicates the original file type is java source file. */ JAVA, /** * Indicates the original file type is proto file. */ PROTO; } private final Label targetLabel; private final Iterable<Artifact> objcSrcs; private final Iterable<Artifact> objcHdrs; private final PathFragment objcFilePath; private final SourceType sourceType; private final Iterable<PathFragment> headerSearchPaths; /** * Constructs a J2ObjcSource containing target information for j2objc transpilation. * * @param targetLabel the @{code Label} of the associated target. * @param objcSrcs the {@code Iterable} containing objc source files generated by J2ObjC * @param objcHdrs the {@code Iterable} containing objc header files generated by J2ObjC * @param objcFilePath the {@code PathFragment} under which all the generated objc files are. It * can be used as header search path for objc compilations. * @param sourceType the type of files from which the ObjC files are generated. * @param headerSearchPaths the {@code Iterable} of header search paths necessary for compiling * the generated J2ObjC sources in {@link objcSrcs} */ public J2ObjcSource(Label targetLabel, Iterable<Artifact> objcSrcs, Iterable<Artifact> objcHdrs, PathFragment objcFilePath, SourceType sourceType, Iterable<PathFragment> headerSearchPaths) { this.targetLabel = targetLabel; this.objcSrcs = objcSrcs; this.objcHdrs = objcHdrs; this.objcFilePath = objcFilePath; this.sourceType = sourceType; this.headerSearchPaths = headerSearchPaths; } /** * Returns a corresponding {@link J2ObjcSource} with source artifacts replaced by the outputs of * the J2objC dead code removal script, for use after that action has processed the originals. * * <p>The script in question builds a dependency graph with entry classes specified * transitively on j2objc_library rules as roots. Translated files from this (original) * {@link J2ObjcSource} which are reachable in the graph from the roots will be copied over to the * source file paths in the returned pruned {@link J2ObjcSource} with full original contents. * Unreachable files will not be copied over and the artifacts pointed to by the returned pruned * {@link J2ObjcSource} will only contain empty files. * * @param ruleContext the {@link RuleContext} of the current rule */ public J2ObjcSource toPrunedSource(RuleContext ruleContext) { ImmutableList.Builder<Artifact> prunedSourceArtifacts = ImmutableList.builder(); for (Artifact sourceArtifact : getObjcSrcs()) { PathFragment prunedSourceArtifactPath = FileSystemUtils.appendWithoutExtension( sourceArtifact.getRootRelativePath(), "_pruned"); Artifact prunedArtifact = ruleContext.getUniqueDirectoryArtifact("_j2objc_pruned", prunedSourceArtifactPath, ruleContext.getBinOrGenfilesDirectory()); prunedSourceArtifacts.add(prunedArtifact); } return new J2ObjcSource( getTargetLabel(), prunedSourceArtifacts.build(), getObjcHdrs(), getObjcFilePath(), getSourceType(), getHeaderSearchPaths()); } /** * Returns the label of the associated target. */ public Label getTargetLabel() { return targetLabel; } /** * Returns the objc source files generated by J2ObjC. */ public Iterable<Artifact> getObjcSrcs() { return objcSrcs; } /* * Returns the objc header files generated by J2ObjC */ public Iterable<Artifact> getObjcHdrs() { return objcHdrs; } /** * Returns the {@code PathFragment} which represents a directory where the generated ObjC files * reside. */ public PathFragment getObjcFilePath() { return objcFilePath; } /** * Returns a list of header search paths necessary for compiling the generated J2ObjC sources. */ public Iterable<PathFragment> getHeaderSearchPaths() { return headerSearchPaths; } /** * Returns the type of files from which the ObjC files inside this object are generated. */ public SourceType getSourceType() { return sourceType; } /** * Returns whether this {@link J2ObjcSource} contains any ObjC source (.m, .mm) files. */ public boolean hasSourceFiles() { return !Iterables.isEmpty(objcSrcs); } @Override public final boolean equals(Object other) { if (!(other instanceof J2ObjcSource)) { return false; } J2ObjcSource that = (J2ObjcSource) other; return Objects.equal(this.targetLabel, that.targetLabel) && Iterators.elementsEqual(this.objcSrcs.iterator(), that.objcSrcs.iterator()) && Iterators.elementsEqual(this.objcHdrs.iterator(), that.objcHdrs.iterator()) && Objects.equal(this.objcFilePath, that.objcFilePath) && this.sourceType == that.sourceType && Iterators.elementsEqual( this.headerSearchPaths.iterator(), that.headerSearchPaths.iterator()); } @Override public int hashCode() { return Objects.hashCode(targetLabel, objcSrcs, objcHdrs, objcFilePath, sourceType, headerSearchPaths); } }