All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.google.errorprone.refaster.PlaceholderMethod Maven / Gradle / Ivy

There is a newer version: 2.28.0
Show newest version
/*
 * Copyright 2014 The Error Prone Authors.
 *
 * 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.errorprone.refaster;

import com.google.auto.value.AutoValue;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.collect.ClassToInstanceMap;
import com.google.common.collect.ImmutableClassToInstanceMap;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Maps;
import com.google.errorprone.VisitorState;
import com.google.errorprone.matchers.Matcher;
import com.google.errorprone.refaster.UPlaceholderExpression.PlaceholderParamIdent;
import com.google.errorprone.refaster.annotation.Matches;
import com.google.errorprone.refaster.annotation.MayOptionallyUse;
import com.google.errorprone.refaster.annotation.NotMatches;
import com.google.errorprone.refaster.annotation.OfKind;
import com.google.errorprone.refaster.annotation.Placeholder;
import com.sun.source.tree.ExpressionTree;
import com.sun.source.tree.Tree;
import com.sun.tools.javac.tree.JCTree.JCExpression;
import com.sun.tools.javac.tree.JCTree.JCStatement;
import com.sun.tools.javac.util.List;
import java.io.Serializable;
import java.lang.annotation.Annotation;
import java.util.Arrays;
import java.util.Set;

/**
 * Representation of a {@code Refaster} placeholder method, which can represent an arbitrary
 * operation on a specific set of expressions.
 *
 * @author [email protected] (Louis Wasserman)
 */
@AutoValue
abstract class PlaceholderMethod implements Serializable {
  static PlaceholderMethod create(
      CharSequence name,
      UType returnType,
      ImmutableMap> parameters,
      ClassToInstanceMap annotations) {
    final boolean allowsIdentity = annotations.getInstance(Placeholder.class).allowsIdentity();
    final Class> matchesClass =
        annotations.containsKey(Matches.class)
            ? UTemplater.getValue(annotations.getInstance(Matches.class))
            : null;
    final Class> notMatchesClass =
        annotations.containsKey(NotMatches.class)
            ? UTemplater.getValue(annotations.getInstance(NotMatches.class))
            : null;
    final Predicate allowedKinds =
        annotations.containsKey(OfKind.class)
            ? Predicates.in(Arrays.asList(annotations.getInstance(OfKind.class).value()))
            : Predicates.alwaysTrue();
    class PlaceholderMatcher implements Matcher {

      @Override
      public boolean matches(ExpressionTree t, VisitorState state) {
        try {
          return (allowsIdentity || !(t instanceof PlaceholderParamIdent))
              && (matchesClass == null || matchesClass.newInstance().matches(t, state))
              && (notMatchesClass == null || !notMatchesClass.newInstance().matches(t, state))
              && allowedKinds.apply(t.getKind());
        } catch (ReflectiveOperationException e) {
          throw new RuntimeException(e);
        }
      }
    }
    return new AutoValue_PlaceholderMethod(
        StringName.of(name),
        returnType,
        parameters,
        new PlaceholderMatcher(),
        ImmutableClassToInstanceMap.copyOf(annotations));
  }

  abstract StringName name();

  abstract UType returnType();

  abstract ImmutableMap>
      annotatedParameters();

  abstract Matcher matcher();

  abstract ImmutableClassToInstanceMap annotations();

  ImmutableSet parameters() {
    return annotatedParameters().keySet();
  }

  /** Parameters which must be referenced in any tree matched to this placeholder. */
  Set requiredParameters() {
    return Maps.filterValues(
            annotatedParameters(),
            (ImmutableClassToInstanceMap annotations) ->
                !annotations.containsKey(MayOptionallyUse.class))
        .keySet();
  }

  PlaceholderExpressionKey exprKey() {
    return new PlaceholderExpressionKey(name().contents(), this);
  }

  PlaceholderBlockKey blockKey() {
    return new PlaceholderBlockKey(name().contents(), this);
  }

  static final class PlaceholderExpressionKey extends Bindings.Key
      implements Comparable {
    final PlaceholderMethod method;

    private PlaceholderExpressionKey(String str, PlaceholderMethod method) {
      super(str);
      this.method = method;
    }

    @Override
    public int compareTo(PlaceholderExpressionKey o) {
      return getIdentifier().compareTo(o.getIdentifier());
    }
  }

  static final class PlaceholderBlockKey extends Bindings.Key> {
    final PlaceholderMethod method;

    private PlaceholderBlockKey(String str, PlaceholderMethod method) {
      super(str);
      this.method = method;
    }
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy