Пример #1
0
  /**
   * Creates and returns a rule instance.
   *
   * <p>It is the caller's responsibility to add the rule to the package (the caller may choose not
   * to do so if, for example, the rule has errors).
   */
  static Rule createRule(
      Package.Builder pkgBuilder,
      RuleClass ruleClass,
      BuildLangTypedAttributeValuesMap attributeValues,
      EventHandler eventHandler,
      @Nullable FuncallExpression ast,
      Location location,
      @Nullable Environment env)
      throws InvalidRuleException, InterruptedException {
    Preconditions.checkNotNull(ruleClass);
    String ruleClassName = ruleClass.getName();
    Object nameObject = attributeValues.getAttributeValue("name");
    if (nameObject == null) {
      throw new InvalidRuleException(ruleClassName + " rule has no 'name' attribute");
    } else if (!(nameObject instanceof String)) {
      throw new InvalidRuleException(ruleClassName + " 'name' attribute must be a string");
    }
    String name = (String) nameObject;
    Label label;
    try {
      // Test that this would form a valid label name -- in particular, this
      // catches cases where Makefile variables $(foo) appear in "name".
      label = pkgBuilder.createLabel(name);
    } catch (LabelSyntaxException e) {
      throw new InvalidRuleException("illegal rule name: " + name + ": " + e.getMessage());
    }
    boolean inWorkspaceFile = pkgBuilder.isWorkspace();
    if (ruleClass.getWorkspaceOnly() && !inWorkspaceFile) {
      throw new RuleFactory.InvalidRuleException(
          ruleClass + " must be in the WORKSPACE file " + "(used by " + label + ")");
    } else if (!ruleClass.getWorkspaceOnly() && inWorkspaceFile) {
      throw new RuleFactory.InvalidRuleException(
          ruleClass + " cannot be in the WORKSPACE file " + "(used by " + label + ")");
    }

    AttributesAndLocation generator =
        generatorAttributesForMacros(attributeValues, env, location, label);
    try {
      return ruleClass.createRule(
          pkgBuilder,
          label,
          generator.attributes,
          eventHandler,
          ast,
          generator.location,
          new AttributeContainer(ruleClass));
    } catch (LabelSyntaxException e) {
      throw new RuleFactory.InvalidRuleException(ruleClass + " " + e.getMessage());
    }
  }
Пример #2
0
 private Package deserializeInternal(InputStream in)
     throws PackageDeserializationException, IOException, InterruptedException {
   // Read the initial Package message so we have the data to initialize the builder. We will read
   // the Targets in individually later.
   Build.Package packagePb = Build.Package.parseDelimitedFrom(in);
   Package.Builder builder;
   try {
     builder =
         new Package.Builder(
             PackageIdentifier.create(
                 packagePb.getRepository(), new PathFragment(packagePb.getName())),
             null);
   } catch (LabelSyntaxException e) {
     throw new PackageDeserializationException(e);
   }
   StoredEventHandler eventHandler = new StoredEventHandler();
   deserializeInternal(packagePb, eventHandler, builder, in);
   builder.addEvents(eventHandler.getEvents());
   return builder.build();
 }
Пример #3
0
 /**
  * Creates a {@link Rule} instance, adds it to the {@link Package.Builder} and returns it.
  *
  * @param pkgBuilder the under-construction {@link Package.Builder} to which the rule belongs
  * @param ruleClass the {@link RuleClass} of the rule
  * @param attributeValues a {@link BuildLangTypedAttributeValuesMap} mapping attribute names to
  *     attribute values of build-language type. Each attribute must be defined for this class of
  *     rule, and have a build-language-typed value which can be converted to the appropriate
  *     native type of the attribute (i.e. via {@link BuildType#selectableConvert}). There must be
  *     a map entry for each non-optional attribute of this class of rule.
  * @param eventHandler a eventHandler on which errors and warnings are reported during rule
  *     creation
  * @param ast the abstract syntax tree of the rule expression (optional)
  * @param location the location at which this rule was declared
  * @param env the lexical environment of the function call which declared this rule (optional)
  * @throws InvalidRuleException if the rule could not be constructed for any reason (e.g. no
  *     {@code name} attribute is defined)
  * @throws NameConflictException if the rule's name or output files conflict with others in this
  *     package
  * @throws InterruptedException if interrupted
  */
 static Rule createAndAddRule(
     Package.Builder pkgBuilder,
     RuleClass ruleClass,
     BuildLangTypedAttributeValuesMap attributeValues,
     EventHandler eventHandler,
     @Nullable FuncallExpression ast,
     Location location,
     @Nullable Environment env)
     throws InvalidRuleException, NameConflictException, InterruptedException {
   Rule rule =
       createRule(pkgBuilder, ruleClass, attributeValues, eventHandler, ast, location, env);
   pkgBuilder.addRule(rule);
   return rule;
 }
Пример #4
0
  /**
   * Creates a rule with the attribute values that are already parsed.
   *
   * <p><b>WARNING:</b> This assumes that the attribute values here have the right type and bypasses
   * some sanity checks. If they are of the wrong type, everything will come down burning.
   */
  @SuppressWarnings("unchecked")
  private static Rule createRuleWithParsedAttributeValues(
      RuleClass ruleClass,
      Label label,
      Package.Builder pkgBuilder,
      Location ruleLocation,
      Map<String, ParsedAttributeValue> attributeValues,
      EventHandler eventHandler,
      AttributeContainer attributeContainer)
      throws LabelSyntaxException, InterruptedException {
    Rule rule =
        pkgBuilder.newRuleWithLabelAndAttrContainer(
            label, ruleClass, null, ruleLocation, attributeContainer);
    rule.checkValidityPredicate(eventHandler);

    for (Attribute attribute : rule.getRuleClassObject().getAttributes()) {
      ParsedAttributeValue value = attributeValues.get(attribute.getName());
      if (attribute.isMandatory()) {
        Preconditions.checkState(value != null);
      }

      if (value == null) {
        continue;
      }

      rule.setAttributeValue(attribute, value.value, value.explicitlySpecified);
      ruleClass.checkAllowedValues(rule, attribute, eventHandler);

      if (attribute.getName().equals("visibility")) {
        // TODO(bazel-team): Verify that this cast works
        rule.setVisibility(PackageFactory.getVisibility((List<Label>) value.value));
      }
    }

    rule.populateOutputFiles(eventHandler, pkgBuilder);
    Preconditions.checkState(!rule.containsErrors());
    return rule;
  }
Пример #5
0
  /**
   * Deserialize a package from its representation as a protocol message. The inverse of {@link
   * PackageSerializer#serialize}.
   *
   * @throws IOException
   * @throws InterruptedException
   */
  private void deserializeInternal(
      Build.Package packagePb,
      StoredEventHandler eventHandler,
      Package.Builder builder,
      InputStream in)
      throws PackageDeserializationException, IOException, InterruptedException {
    Path buildFile = packageDeserializationEnvironment.getPath(packagePb.getBuildFilePath());
    Preconditions.checkNotNull(buildFile);
    DeserializationContext context = new DeserializationContext(builder);
    builder.setFilename(buildFile);

    if (packagePb.hasDefaultVisibilitySet() && packagePb.getDefaultVisibilitySet()) {
      builder.setDefaultVisibility(
          PackageFactory.getVisibility(
              deserializeLabels(packagePb.getDefaultVisibilityLabelList())));
    }

    // It's important to do this after setting the default visibility, since that implicitly sets
    // this bit to true
    builder.setDefaultVisibilitySet(packagePb.getDefaultVisibilitySet());
    if (packagePb.hasDefaultTestonly()) {
      builder.setDefaultTestonly(packagePb.getDefaultTestonly());
    }
    if (packagePb.hasDefaultDeprecation()) {
      builder.setDefaultDeprecation(packagePb.getDefaultDeprecation());
    }

    builder.setDefaultCopts(packagePb.getDefaultCoptList());
    if (packagePb.hasDefaultHdrsCheck()) {
      builder.setDefaultHdrsCheck(packagePb.getDefaultHdrsCheck());
    }
    if (packagePb.hasDefaultLicense()) {
      builder.setDefaultLicense(deserializeLicense(packagePb.getDefaultLicense()));
    }
    builder.setDefaultDistribs(deserializeDistribs(packagePb.getDefaultDistribList()));

    for (String subinclude : packagePb.getSubincludeLabelList()) {
      Label label = deserializeLabel(subinclude);
      builder.addSubinclude(label, null);
    }

    ImmutableList.Builder<Label> skylarkFileDependencies = ImmutableList.builder();
    for (String skylarkFile : packagePb.getSkylarkLabelList()) {
      skylarkFileDependencies.add(deserializeLabel(skylarkFile));
    }
    builder.setSkylarkFileDependencies(skylarkFileDependencies.build());

    MakeEnvironment.Builder makeEnvBuilder = new MakeEnvironment.Builder();
    for (Build.MakeVar makeVar : packagePb.getMakeVariableList()) {
      for (Build.MakeVarBinding binding : makeVar.getBindingList()) {
        makeEnvBuilder.update(
            makeVar.getName(), binding.getValue(), binding.getPlatformSetRegexp());
      }
    }
    builder.setMakeEnv(makeEnvBuilder);

    for (Build.Event event : packagePb.getEventList()) {
      deserializeEvent(eventHandler, event);
    }

    if (packagePb.hasContainsErrors() && packagePb.getContainsErrors()) {
      builder.setContainsErrors();
    }

    builder.setWorkspaceName(packagePb.getWorkspaceName());

    deserializeTargets(in, context);
  }