<commit_before>/*
 * Copyright 2012 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.bugpatterns;

import static com.google.errorprone.BugPattern.SeverityLevel.ERROR;
import static com.google.errorprone.matchers.Matchers.anyOf;
import static com.google.errorprone.matchers.Matchers.staticMethod;
import static com.sun.source.tree.Tree.Kind.CLASS;
import static com.sun.source.tree.Tree.Kind.IDENTIFIER;
import static com.sun.source.tree.Tree.Kind.MEMBER_SELECT;
import static com.sun.source.tree.Tree.Kind.METHOD_INVOCATION;
import static javax.lang.model.element.Modifier.STATIC;

import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.errorprone.BugPattern;
import com.google.errorprone.BugPattern.ProvidesFix;
import com.google.errorprone.VisitorState;
import com.google.errorprone.bugpatterns.BugChecker.AssignmentTreeMatcher;
import com.google.errorprone.bugpatterns.BugChecker.VariableTreeMatcher;
import com.google.errorprone.fixes.Fix;
import com.google.errorprone.fixes.SuggestedFix;
import com.google.errorprone.matchers.Description;
import com.google.errorprone.matchers.Matcher;
import com.google.errorprone.util.ASTHelpers;
import com.sun.source.tree.AssignmentTree;
import com.sun.source.tree.ExpressionTree;
import com.sun.source.tree.MemberSelectTree;
import com.sun.source.tree.MethodInvocationTree;
import com.sun.source.tree.ParenthesizedTree;
import com.sun.source.tree.Tree;
import com.sun.source.tree.TypeCastTree;
import com.sun.source.tree.VariableTree;
import com.sun.source.util.SimpleTreeVisitor;
import com.sun.tools.javac.code.Flags;
import com.sun.tools.javac.code.Symbol;
import com.sun.tools.javac.code.Type;

/**
 * TODO(eaftan): Consider cases where the parent is not a statement or there is no parent?
 *
 * @author <EMAIL> (<NAME>)
 * @author <EMAIL> (<NAME>)
 */
@BugPattern(
    name = "SelfAssignment",
    summary = "Variable assigned to itself",
    severity = ERROR,
    providesFix = ProvidesFix.REQUIRES_HUMAN_ATTENTION)
public class SelfAssignment extends BugChecker
    implements AssignmentTreeMatcher, VariableTreeMatcher {
  private static final Matcher<MethodInvocationTree> NON_NULL_MATCHER =
      anyOf(
          staticMethod().onClass("com.google.common.base.Preconditions").named("checkNotNull"),
          staticMethod().onClass("java.util.Objects").named("requireNonNull"));

  @Override
  public Description matchAssignment(AssignmentTree tree, VisitorState state) {
    ExpressionTree expression = stripNullCheck(tree.getExpression(), state);
    // TODO(cushon): consider handling assignment expressions too, i.e. `x = y = x`
    expression = skipCast(expression);
    if (ASTHelpers.sameVariable(tree.getVariable(), expression)) {<commit_msg>Expand SelfAssignment to cover the Precondition-style APIs in c.g.c.time.Durations,c.g.protobuf.util.{Durations,Timestamps}.<commit_after>/*
 * Copyright 2012 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.bugpatterns;

import static com.google.errorprone.BugPattern.SeverityLevel.ERROR;
import static com.google.errorprone.matchers.Matchers.anyOf;
import static com.google.errorprone.matchers.Matchers.staticMethod;
import static com.sun.source.tree.Tree.Kind.CLASS;
import static com.sun.source.tree.Tree.Kind.IDENTIFIER;
import static com.sun.source.tree.Tree.Kind.MEMBER_SELECT;
import static com.sun.source.tree.Tree.Kind.METHOD_INVOCATION;
import static javax.lang.model.element.Modifier.STATIC;

import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.errorprone.BugPattern;
import com.google.errorprone.BugPattern.ProvidesFix;
import com.google.errorprone.VisitorState;
import com.google.errorprone.bugpatterns.BugChecker.AssignmentTreeMatcher;
import com.google.errorprone.bugpatterns.BugChecker.VariableTreeMatcher;
import com.google.errorprone.fixes.Fix;
import com.google.errorprone.fixes.SuggestedFix;
import com.google.errorprone.matchers.Description;
import com.google.errorprone.matchers.Matcher;
import com.google.errorprone.util.ASTHelpers;
import com.sun.source.tree.AssignmentTree;
import com.sun.source.tree.ExpressionTree;
import com.sun.source.tree.MemberSelectTree;
import com.sun.source.tree.MethodInvocationTree;
import com.sun.source.tree.ParenthesizedTree;
import com.sun.source.tree.Tree;
import com.sun.source.tree.TypeCastTree;
import com.sun.source.tree.VariableTree;
import com.sun.source.util.SimpleTreeVisitor;
import com.sun.tools.javac.code.Flags;
import com.sun.tools.javac.code.Symbol;
import com.sun.tools.javac.code.Type;

/**
 * TODO(eaftan): Consider cases where the parent is not a statement or there is no parent?
 *
 * @author <EMAIL> (<NAME>)
 * @author <EMAIL> (<NAME>)
 */
@BugPattern(
    name = "SelfAssignment",
    summary = "Variable assigned to itself",
    severity = ERROR,
    providesFix = ProvidesFix.REQUIRES_HUMAN_ATTENTION)
public class SelfAssignment extends BugChecker
    implements AssignmentTreeMatcher, VariableTreeMatcher {
  private static final Matcher<MethodInvocationTree> NON_NULL_MATCHER =
      anyOf(
          staticMethod().onClass("java.util.Objects").named("requireNonNull"),
          staticMethod().onClass("com.google.common.base.Preconditions").named("checkNotNull"),
          staticMethod()
              .onClass("com.google.common.time.Durations")
              .namedAnyOf("checkNotNegative", "checkPositive"),
          staticMethod()
              .onClass("com.google.protobuf.util.Durations")
              .namedAnyOf("checkNotNegative", "checkPositive", "checkValid"),
          staticMethod().onClass("com.google.protobuf.util.Timestamps").named("checkValid"));

  @Override
  public Description matchAssignment(AssignmentTree tree, VisitorState state) {
    ExpressionTree expression = stripNullCheck(tree.getExpression(), state);
    // TODO(cushon): consider handling assignment expressions too, i.e. `x = y = x`
    expression = skipCast(expression);
    if (ASTHelpers.sameVariable(tree.getVariable(), expression)) {
{'fraction_non_alphanumeric': 0.10621689434067466, 'fraction_numerical': 0.002230275996654586, 'mean_word_length': 4.88597210828548, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3229852', 'n_tokens_mistral': 2108, 'n_tokens_neox': 2098, 'n_words': 486}