ReassignmentFinder { @CheckForNull public static ExpressionTree getClosestReassignmentOrDeclarationExpression(Tree startingPoint, Symbol referenceSymbol) { Tree result = referenceSymbol.declaration(); List<IdentifierTree> usages = referenceSymbol.usages(); if (usages.size() != 1) { List<AssignmentExpressionTree> reassignments = getReassignments(referenceSymbol.owner().declaration(), usages); SyntaxToken startPointToken = startingPoint.firstToken(); Tree lastReassignment = getClosestReassignment(startPointToken, reassignments); if (lastReassignment != null) { result = lastReassignment; } } ExpressionTree initializerOrExpression = getInitializerOrExpression(result); if (initializerOrExpression == startingPoint) { return getClosestReassignmentOrDeclarationExpression(result, referenceSymbol); } return initializerOrExpression; } private  ReassignmentFinder(); @CheckForNull static ExpressionTree getClosestReassignmentOrDeclarationExpression(Tree startingPoint, Symbol referenceSymbol); @CheckForNull static ExpressionTree getInitializerOrExpression(@Nullable Tree tree); static List<AssignmentExpressionTree> getReassignments(@Nullable Tree ownerDeclaration, List<IdentifierTree> usages);  }
@Test void in_enum() { String code = newCode( "enum E { E1 {} }", "E foo() {", " return E.E1;", "}"); ClassTree classTree = classTree(code); ClassTree enumClass = (ClassTree) classTree.members().get(0); VariableTree constant = (VariableTree) enumClass.members().get(0); List<StatementTree> statements = ((MethodTree) classTree.members().get(1)).block().body(); ReturnStatementTree returnStatement = (ReturnStatementTree) statements.get(0); assertThat(ReassignmentFinder.getClosestReassignmentOrDeclarationExpression(returnStatement.expression(), constant.symbol())) .isEqualTo(constant.initializer()); }