Skip to content

Commit

Permalink
Skylark: native module is updated with exports_files and package_group.
Browse files Browse the repository at this point in the history
--
MOS_MIGRATED_REVID=89386727
  • Loading branch information
Googler authored and hanwen committed Mar 24, 2015
1 parent 8fc603c commit 1048057
Show file tree
Hide file tree
Showing 2 changed files with 133 additions and 75 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,7 @@ public void onCompletion() {
/**
* Constructs a {@code PackageFactory} instance with the given rule factory.
*/
@VisibleForTesting
public PackageFactory(RuleClassProvider ruleClassProvider) {
this(ruleClassProvider, null, ImmutableList.<EnvironmentExtension>of());
}
Expand All @@ -354,7 +355,6 @@ public PackageFactory(RuleClassProvider ruleClassProvider,
* Constructs a {@code PackageFactory} instance with a specific glob path translator
* and rule factory.
*/
@VisibleForTesting
public PackageFactory(RuleClassProvider ruleClassProvider,
Map<String, String> platformSetRegexps,
Iterable<EnvironmentExtension> environmentExtensions) {
Expand Down Expand Up @@ -460,12 +460,12 @@ private static Function newGlobFunction(
@Override
public Object call(Object[] namedArguments, FuncallExpression ast, Environment env)
throws EvalException, ConversionException, InterruptedException {
return globCall(originalContext, async, ast, env, namedArguments);
return callGlob(originalContext, async, ast, env, namedArguments);
}
};
}

static Object globCall(@Nullable PackageContext originalContext, boolean async,
static Object callGlob(@Nullable PackageContext originalContext, boolean async,
FuncallExpression ast, Environment env, Object[] namedArguments)
throws EvalException, ConversionException, InterruptedException {
// Skylark build extensions need to get the PackageContext from the Environment;
Expand Down Expand Up @@ -619,60 +619,64 @@ public Object call(Object[] namedArgs, FuncallExpression ast)
* Returns a function-value implementing "exports_files" in the specified
* package context.
*/
private static Function newExportsFilesFunction(final PackageContext context) {
final Package.LegacyBuilder pkgBuilder = context.pkgBuilder;
private static Function newExportsFilesFunction() {
List<String> params = ImmutableList.of("srcs", "visibility", "licenses");
return new MixedModeFunction("exports_files", params, 1, false) {
@Override
public Object call(Object[] namedArgs, FuncallExpression ast)
public Object call(Object[] namedArgs, FuncallExpression ast, Environment env)
throws EvalException, ConversionException {
return callExportsFiles(ast, env, namedArgs);
}
};
}

List<String> files = Type.STRING_LIST.convert(namedArgs[0], "'exports_files' operand");

RuleVisibility visibility = namedArgs[1] == null
? ConstantRuleVisibility.PUBLIC
: getVisibility(Type.LABEL_LIST.convert(
namedArgs[1],
"'exports_files' operand",
pkgBuilder.getBuildFileLabel()));
License license = namedArgs[2] == null
? null
: Type.LICENSE.convert(namedArgs[2], "'exports_files' operand");

for (String file : files) {
String errorMessage = LabelValidator.validateTargetName(file);
if (errorMessage != null) {
throw new EvalException(ast.getLocation(), errorMessage);
}
try {
InputFile inputFile = pkgBuilder.createInputFile(file, ast.getLocation());
if (inputFile.isVisibilitySpecified()
&& inputFile.getVisibility() != visibility) {
throw new EvalException(ast.getLocation(),
String.format("visibility for exported file '%s' declared twice",
inputFile.getName()));
}
if (license != null && inputFile.isLicenseSpecified()) {
throw new EvalException(ast.getLocation(),
String.format("licenses for exported file '%s' declared twice",
inputFile.getName()));
}
if (license == null && pkgBuilder.getDefaultLicense() == License.NO_LICENSE
&& pkgBuilder.getBuildFileLabel().toString().startsWith("//third_party/")) {
throw new EvalException(ast.getLocation(),
"third-party file '" + inputFile.getName() + "' lacks a license declaration "
+ "with one of the following types: notice, reciprocal, permissive, "
+ "restricted, unencumbered, by_exception_only");
}

pkgBuilder.setVisibilityAndLicense(inputFile, visibility, license);
} catch (Package.Builder.GeneratedLabelConflict e) {
throw new EvalException(ast.getLocation(), e.getMessage());
}
static Object callExportsFiles(FuncallExpression ast, Environment env, Object[] namedArgs)
throws EvalException, ConversionException {
Package.LegacyBuilder pkgBuilder = getContext(env, ast).pkgBuilder;
List<String> files = Type.STRING_LIST.convert(namedArgs[0], "'exports_files' operand");

RuleVisibility visibility = namedArgs[1] == null
? ConstantRuleVisibility.PUBLIC
: getVisibility(Type.LABEL_LIST.convert(
namedArgs[1],
"'exports_files' operand",
pkgBuilder.getBuildFileLabel()));
License license = namedArgs[2] == null
? null
: Type.LICENSE.convert(namedArgs[2], "'exports_files' operand");

for (String file : files) {
String errorMessage = LabelValidator.validateTargetName(file);
if (errorMessage != null) {
throw new EvalException(ast.getLocation(), errorMessage);
}
try {
InputFile inputFile = pkgBuilder.createInputFile(file, ast.getLocation());
if (inputFile.isVisibilitySpecified()
&& inputFile.getVisibility() != visibility) {
throw new EvalException(ast.getLocation(),
String.format("visibility for exported file '%s' declared twice",
inputFile.getName()));
}
return Environment.NONE;
if (license != null && inputFile.isLicenseSpecified()) {
throw new EvalException(ast.getLocation(),
String.format("licenses for exported file '%s' declared twice",
inputFile.getName()));
}
if (license == null && pkgBuilder.getDefaultLicense() == License.NO_LICENSE
&& pkgBuilder.getBuildFileLabel().toString().startsWith("//third_party/")) {
throw new EvalException(ast.getLocation(),
"third-party file '" + inputFile.getName() + "' lacks a license declaration "
+ "with one of the following types: notice, reciprocal, permissive, "
+ "restricted, unencumbered, by_exception_only");
}

pkgBuilder.setVisibilityAndLicense(inputFile, visibility, license);
} catch (Package.Builder.GeneratedLabelConflict e) {
throw new EvalException(ast.getLocation(), e.getMessage());
}
};
}
return Environment.NONE;
}

/**
Expand Down Expand Up @@ -718,36 +722,42 @@ public Object call(Object[] args, FuncallExpression ast) {
};
}

private static Function newPackageGroupFunction(final PackageContext context) {
private static Function newPackageGroupFunction() {
List<String> params = ImmutableList.of("name", "packages", "includes");
return new MixedModeFunction("package_group", params, 1, true) {
@Override
public Object call(Object[] namedArgs, FuncallExpression ast)
public Object call(Object[] namedArgs, FuncallExpression ast, Environment env)
throws EvalException, ConversionException {
Preconditions.checkState(namedArgs[0] != null);
String name = Type.STRING.convert(namedArgs[0], "'package_group' argument");
List<String> packages = namedArgs[1] == null
? Collections.<String>emptyList()
: Type.STRING_LIST.convert(namedArgs[1], "'package_group' argument");
List<Label> includes = namedArgs[2] == null
? Collections.<Label>emptyList()
: Type.LABEL_LIST.convert(namedArgs[2], "'package_group argument'",
context.pkgBuilder.getBuildFileLabel());

try {
context.pkgBuilder.addPackageGroup(name, packages, includes, context.eventHandler,
ast.getLocation());
return Environment.NONE;
} catch (Label.SyntaxException e) {
throw new EvalException(ast.getLocation(),
"package group has invalid name: " + name + ": " + e.getMessage());
} catch (Package.NameConflictException e) {
throw new EvalException(ast.getLocation(), e.getMessage());
}
return callPackageFunction(ast, env, namedArgs);
}
};
}

static Object callPackageFunction(FuncallExpression ast, Environment env, Object[] namedArgs)
throws EvalException, ConversionException {
PackageContext context = getContext(env, ast);
Preconditions.checkState(namedArgs[0] != null);
String name = Type.STRING.convert(namedArgs[0], "'package_group' argument");
List<String> packages = namedArgs[1] == null
? Collections.<String>emptyList()
: Type.STRING_LIST.convert(namedArgs[1], "'package_group' argument");
List<Label> includes = namedArgs[2] == null
? Collections.<Label>emptyList()
: Type.LABEL_LIST.convert(namedArgs[2], "'package_group argument'",
context.pkgBuilder.getBuildFileLabel());

try {
context.pkgBuilder.addPackageGroup(name, packages, includes, context.eventHandler,
ast.getLocation());
return Environment.NONE;
} catch (Label.SyntaxException e) {
throw new EvalException(ast.getLocation(),
"package group has invalid name: " + name + ": " + e.getMessage());
} catch (Package.NameConflictException e) {
throw new EvalException(ast.getLocation(), e.getMessage());
}
}

public static RuleVisibility getVisibility(List<Label> original) {
RuleVisibility result;

Expand Down Expand Up @@ -1105,8 +1115,8 @@ private void buildPkgEnv(Environment pkgEnv, String packageName,
pkgEnv.update("glob", newGlobFunction(context, /*async=*/false));
pkgEnv.update("mocksubinclude", newMockSubincludeFunction(context));
pkgEnv.update("licenses", newLicensesFunction(context));
pkgEnv.update("exports_files", newExportsFilesFunction(context));
pkgEnv.update("package_group", newPackageGroupFunction(context));
pkgEnv.update("exports_files", newExportsFilesFunction());
pkgEnv.update("package_group", newPackageGroupFunction());
pkgEnv.update("package", newPackageFunction(packageArguments));
pkgEnv.update("subinclude", newSubincludeFunction());
pkgEnv.update("environment_group", newEnvironmentGroupFunction(context));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,13 +55,61 @@ public class SkylarkNativeModule {
@Override
public Object call(Map<String, Object> kwargs, FuncallExpression ast, Environment env)
throws EvalException, ConversionException, InterruptedException {
return PackageFactory.globCall(null, false, ast, env, new Object[] {
return PackageFactory.callGlob(null, false, ast, env, new Object[] {
kwargs.get("includes"),
kwargs.get("excludes"),
kwargs.get("exclude_directories")
});
}
};

@SkylarkBuiltin(name = "package_group", objectType = SkylarkNativeModule.class,
doc = "This function defines a set of packages and assigns a label to the group. "
+ "The label can be referenced in <code>visibility</code> attributes.",
mandatoryParams = {
@Param(name = "name", type = String.class,
doc = "A unique name for this rule.")},
optionalParams = {
@Param(name = "packages", type = SkylarkList.class, generic1 = String.class,
doc = "A complete enumeration of packages in this group."),
@Param(name = "includes", type = SkylarkList.class, generic1 = String.class,
doc = "Other package groups that are included in this one.")})
private static final SkylarkFunction packageGroup = new SkylarkFunction("package_group") {
@Override
public Object call(Map<String, Object> kwargs, FuncallExpression ast, Environment env)
throws EvalException, ConversionException {
return PackageFactory.callPackageFunction(ast, env, new Object[] {
kwargs.get("name"),
kwargs.get("packages"),
kwargs.get("includes")
});
}
};

@SkylarkBuiltin(name = "exports_files", objectType = SkylarkNativeModule.class,
doc = "Specifies a list of files belonging to this package that are exported to other "
+ "packages but not otherwise mentioned.",
mandatoryParams = {
@Param(name = "srcs", type = SkylarkList.class, generic1 = String.class,
doc = "The list of files to export.")},
optionalParams = {
@Param(name = "visibility", type = SkylarkList.class, generic1 = String.class,
doc = "A visibility declaration can to be specified. The files will be visible to the "
+ "targets specified. If no visibility is specified, the files will be visible to "
+ "every package."),
@Param(name = "licenses", type = SkylarkList.class, generic1 = String.class,
doc = "Lincenses to be specified.")})
private static final SkylarkFunction exportsFiles = new SkylarkFunction("exports_files") {
@Override
public Object call(Map<String, Object> kwargs, FuncallExpression ast, Environment env)
throws EvalException, ConversionException {
return PackageFactory.callExportsFiles(ast, env, new Object[] {
kwargs.get("srcs"),
kwargs.get("visibility"),
kwargs.get("licenses")
});
}
};

public static final SkylarkNativeModule NATIVE_MODULE = new SkylarkNativeModule();
}

0 comments on commit 1048057

Please sign in to comment.