/*
* Copyright 2009-2017 the original author or 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 org.codehaus.groovy.eclipse.refactoring.core.extract;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.codehaus.groovy.ast.ClassNode;
import org.codehaus.groovy.ast.FieldNode;
import org.codehaus.groovy.ast.expr.CastExpression;
import org.codehaus.groovy.ast.expr.ClassExpression;
import org.codehaus.groovy.ast.expr.ConstantExpression;
import org.codehaus.groovy.ast.expr.Expression;
import org.codehaus.groovy.ast.expr.MethodCallExpression;
import org.codehaus.groovy.ast.expr.StaticMethodCallExpression;
import org.codehaus.groovy.ast.expr.VariableExpression;
import org.codehaus.groovy.eclipse.codebrowsing.fragments.ASTFragmentKind;
import org.codehaus.groovy.eclipse.codebrowsing.fragments.BinaryExpressionFragment;
import org.codehaus.groovy.eclipse.codebrowsing.fragments.IASTFragment;
import org.codehaus.groovy.eclipse.codebrowsing.fragments.MethodCallFragment;
import org.codehaus.groovy.eclipse.codebrowsing.fragments.PropertyExpressionFragment;
import org.codehaus.groovy.eclipse.codebrowsing.selection.FindAllOccurrencesVisitor;
import org.codehaus.groovy.eclipse.core.GroovyCore;
import org.codehaus.groovy.eclipse.refactoring.Activator;
import org.codehaus.groovy.eclipse.refactoring.core.utils.ASTTools;
import org.codehaus.groovy.eclipse.refactoring.formatter.DefaultGroovyFormatter;
import org.codehaus.groovy.eclipse.refactoring.formatter.FormatterPreferences;
import org.codehaus.jdt.groovy.model.GroovyCompilationUnit;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.SubProgressMonitor;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IMember;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.NamingConventions;
import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.core.refactoring.CompilationUnitChange;
import org.eclipse.jdt.core.refactoring.descriptors.ExtractConstantDescriptor;
import org.eclipse.jdt.core.refactoring.descriptors.JavaRefactoringDescriptor;
import org.eclipse.jdt.groovy.core.util.ReflectionUtils;
import org.eclipse.jdt.internal.core.refactoring.descriptors.RefactoringSignatureDescriptorFactory;
import org.eclipse.jdt.internal.corext.refactoring.Checks;
import org.eclipse.jdt.internal.corext.refactoring.JDTRefactoringDescriptorComment;
import org.eclipse.jdt.internal.corext.refactoring.JavaRefactoringArguments;
import org.eclipse.jdt.internal.corext.refactoring.JavaRefactoringDescriptorUtil;
import org.eclipse.jdt.internal.corext.refactoring.RefactoringCoreMessages;
import org.eclipse.jdt.internal.corext.refactoring.base.JavaStatusContext;
import org.eclipse.jdt.internal.corext.refactoring.code.ExtractConstantRefactoring;
import org.eclipse.jdt.internal.corext.util.CodeFormatterUtil;
import org.eclipse.jdt.internal.corext.util.JdtFlags;
import org.eclipse.jdt.internal.ui.viewsupport.BasicElementLabels;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.Document;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.TextUtilities;
import org.eclipse.ltk.core.refactoring.Change;
import org.eclipse.ltk.core.refactoring.RefactoringChangeDescriptor;
import org.eclipse.ltk.core.refactoring.RefactoringDescriptor;
import org.eclipse.ltk.core.refactoring.RefactoringStatus;
import org.eclipse.ltk.core.refactoring.RefactoringStatusContext;
import org.eclipse.ltk.core.refactoring.TextEditChangeGroup;
import org.eclipse.ltk.internal.core.refactoring.Messages;
import org.eclipse.text.edits.InsertEdit;
import org.eclipse.text.edits.MalformedTreeException;
import org.eclipse.text.edits.MultiTextEdit;
import org.eclipse.text.edits.ReplaceEdit;
import org.eclipse.text.edits.TextEdit;
import org.eclipse.text.edits.TextEditGroup;
/**
* @author Andrew Eisenberg
*/
public class ExtractGroovyConstantRefactoring extends ExtractConstantRefactoring {
private static final String MODIFIER = "static final";
private IASTFragment selectedFragment;
private GroovyCompilationUnit unit;
private int start = -1, length = -1;
private String constantName;
private boolean insertFirst;
private FieldNode toInsertAfter;
private String constantText;
private String[] fExcludedVariableNames = null;
public ExtractGroovyConstantRefactoring(JavaRefactoringArguments arguments,
RefactoringStatus status) {
super(arguments, status);
}
public ExtractGroovyConstantRefactoring(
GroovyCompilationUnit unit, int offset, int length) {
super(unit, offset, length);
this.unit = unit;
this.start = offset;
// some ASTNodes include whitespace after their ends
// so expand the selection so that these kinds of nodes can be
// selected without the user having to explicitly include the
// whitespace
this.length = expandSelection(start, length);
setSelectionLength(this.length);
}
@Override
public RefactoringStatus checkInitialConditions(IProgressMonitor pm) throws CoreException {
try {
pm.beginTask("", 7);
RefactoringStatus result= Checks.validateEdit(getCu(), getValidationContext());
if (result.hasFatalError()) {
return result;
}
pm.worked(4);
result.merge(checkSelection(new SubProgressMonitor(pm, 3)));
if (result.hasFatalError()) {
return result;
}
ClassNode targetType= getContainingClassNode();
if (targetType == null) {
result.merge(RefactoringStatus.createFatalErrorStatus("Cannot find enclosing Class declaration."));
}
if (targetType.isScript()) {
result.merge(RefactoringStatus.createFatalErrorStatus("Cannot extract a constant to a Script."));
}
if (targetType.isAnnotationDefinition() || targetType.isInterface()) {
setTargetIsInterface(true);
setVisibility(JdtFlags.VISIBILITY_STRING_PUBLIC);
}
if (getSelectedFragment() == null) {
result.merge(RefactoringStatus.createFatalErrorStatus("Illegal expression selected"));
}
return result;
} finally {
pm.done();
}
}
private int expandSelection(int s, int l) {
int end = s + l;
char[] contents = unit.getContents();
while (end < contents.length && (contents[end] == ' ' || contents[end] == '\t')) {
end++;
}
return end - s;
}
private CompilationUnitChange getChange() {
return (CompilationUnitChange) ReflectionUtils.getPrivateField(ExtractConstantRefactoring.class, "fChange", this);
}
private void setChange(CompilationUnitChange change) {
ReflectionUtils.setPrivateField(ExtractConstantRefactoring.class, "fChange", this, change);
}
@Override
public RefactoringStatus checkFinalConditions(IProgressMonitor pm)
throws CoreException {
try {
RefactoringStatus result= new RefactoringStatus();
CompilationUnitChange change = new CompilationUnitChange("Extract Groovy Constant", getCu());
change.setEdit(new MultiTextEdit());
TextEditGroup group = createConstantDeclaration();
change.addChangeGroup(new TextEditChangeGroup(change, group));
for (TextEdit edit : group.getTextEdits()) {
change.addEdit(edit);
}
group = replaceExpressionsWithConstant();
change.addChangeGroup(new TextEditChangeGroup(change, group));
for (TextEdit edit : group.getTextEdits()) {
change.addEdit(edit);
}
setChange(change);
return result;
} catch (MalformedTreeException e) {
throw new CoreException(new Status(IStatus.ERROR, Activator.PLUGIN_ID, e.getMessage(), e));
} catch (BadLocationException e) {
throw new CoreException(new Status(IStatus.ERROR, Activator.PLUGIN_ID, e.getMessage(), e));
} finally {
pm.done();
}
}
private TextEditGroup replaceExpressionsWithConstant() throws JavaModelException {
IASTFragment origExpr = getSelectedFragment();
List<IASTFragment> occurrences;
if (getReplaceAllOccurrences()) {
FindAllOccurrencesVisitor v = new FindAllOccurrencesVisitor(getCu().getModuleNode());
occurrences = v.findOccurrences(origExpr);
} else {
occurrences = Collections.singletonList(origExpr);
}
TextEditGroup msg= new TextEditGroup(RefactoringCoreMessages.ExtractConstantRefactoring_replace);
for (IASTFragment fragment : occurrences) {
String replaceText;
if (getQualifyReferencesWithDeclaringClassName()) {
replaceText = getContainingClassNode().getNameWithoutPackage() + "." + getConstantName();
} else {
replaceText = getConstantName();
}
msg.addTextEdit(new ReplaceEdit(fragment.getStart(), fragment.getLength(), replaceText));
}
return msg;
}
private TextEditGroup createConstantDeclaration() throws MalformedTreeException, BadLocationException {
String constantText = getConstantText();
TextEditGroup msg= new TextEditGroup(RefactoringCoreMessages.ExtractConstantRefactoring_declare_constant);
int insertLocation = findInsertLocation();
msg.addTextEdit(new InsertEdit(insertLocation, constantText));
return msg;
}
/**
* @return
* @throws JavaModelException
*/
private int findInsertLocation() {
if (insertFirst()) {
ClassNode node = getContainingClassNode();
if (node.isScript()) {
int statementStart = node.getModule().getStatementBlock().getStart();
int methodStart;
if (node.getModule().getMethods().size() > 0) {
methodStart = node.getModule().getMethods().get(0).getStart();
} else {
methodStart = Integer.MAX_VALUE;
}
return Math.min(methodStart, statementStart);
} else {
return CharOperation.indexOf('{', getCu().getContents(), node.getNameEnd()) + 1;
}
} else {
return toInsertAfter.getEnd();
}
}
/**
* @return
* @throws BadLocationException
* @throws MalformedTreeException
* @throws JavaModelException
* @throws CoreException
*/
private String getConstantText() throws MalformedTreeException, BadLocationException {
if (constantText == null) {
constantText = createConstantText();
}
return constantText;
}
private String createConstantText() throws MalformedTreeException, BadLocationException {
StringBuilder sb = new StringBuilder();
IJavaProject javaProject = getCu().getJavaProject();
sb.append(CodeFormatterUtil.createIndentString(getIndentLevel(), javaProject));
if (getVisibility().length() > 0) {
sb.append(getVisibility()).append(" ");
}
sb.append(MODIFIER).append(" ").append(getConstantTypeName()).append(constantName).append(" = ").append(
createExpressionText());
IDocument doc = new Document(sb.toString());
DefaultGroovyFormatter formatter = new DefaultGroovyFormatter(doc, new FormatterPreferences(unit), getIndentLevel());
TextEdit edit = formatter.format();
edit.apply(doc);
return getDefaultNewlineCharacterTwice() + doc.get();
}
private String getDefaultNewlineCharacterTwice() {
String newline = TextUtilities.determineLineDelimiter(String.valueOf(unit.getContents()), "\n");
return newline + newline;
}
private int getIndentLevel() {
ClassNode node = getContainingClassNode();
ClassNode containing = node;
int indentLevel = 0;
while (containing != null) {
indentLevel++;
if (containing.getEnclosingMethod() != null) {
indentLevel++;
containing = containing.getEnclosingMethod().getDeclaringClass();
} else {
containing = containing.getOuterClass();
}
}
return indentLevel;
}
/**
* @return
* @throws JavaModelException
*/
private String createExpressionText() {
IASTFragment fragment = getSelectedFragment();
return String.valueOf(unit.getContents()).substring(fragment.getStart(), fragment.getEnd());
}
private boolean insertFirst() {
if(!isDeclarationLocationComputed())
computeConstantDeclarationLocation();
return insertFirst;
}
private boolean isDeclarationLocationComputed() {
return insertFirst || toInsertAfter != null;
}
@Override
public Change createChange(IProgressMonitor monitor) throws CoreException {
ExtractConstantDescriptor descriptor= createRefactoringDescriptor();
getChange().setDescriptor(new RefactoringChangeDescriptor(descriptor));
return getChange();
}
private ExtractConstantDescriptor createRefactoringDescriptor() {
final Map<String, String> arguments= new HashMap<String, String>();
String project= null;
IJavaProject javaProject= getCu().getJavaProject();
if (javaProject != null)
project= javaProject.getElementName();
int flags= JavaRefactoringDescriptor.JAR_REFACTORING | JavaRefactoringDescriptor.JAR_SOURCE_ATTACHMENT;
flags|= RefactoringDescriptor.STRUCTURAL_CHANGE;
String expression = createExpressionText();
final String description= Messages.format(RefactoringCoreMessages.ExtractConstantRefactoring_descriptor_description_short, BasicElementLabels.getJavaElementName(constantName));
final String header= Messages.format(RefactoringCoreMessages.ExtractConstantRefactoring_descriptor_description, new String[] { BasicElementLabels.getJavaElementName(constantName), BasicElementLabels.getJavaCodeString(expression)});
final JDTRefactoringDescriptorComment comment= new JDTRefactoringDescriptorComment(project, this, header);
comment.addSetting(Messages.format(RefactoringCoreMessages.ExtractConstantRefactoring_constant_name_pattern, BasicElementLabels.getJavaElementName(constantName)));
comment.addSetting(Messages.format(RefactoringCoreMessages.ExtractConstantRefactoring_constant_expression_pattern, BasicElementLabels.getJavaCodeString(expression)));
String visibility= "";
if ("".equals(visibility))
visibility= RefactoringCoreMessages.ExtractConstantRefactoring_default_visibility;
comment.addSetting(Messages.format(RefactoringCoreMessages.ExtractConstantRefactoring_visibility_pattern, visibility));
if (getReplaceAllOccurrences()) {
comment.addSetting(RefactoringCoreMessages.ExtractConstantRefactoring_replace_occurrences);
}
if (getQualifyReferencesWithDeclaringClassName()) {
comment.addSetting(RefactoringCoreMessages.ExtractConstantRefactoring_qualify_references);
}
arguments.put(JavaRefactoringDescriptorUtil.ATTRIBUTE_INPUT, JavaRefactoringDescriptorUtil.elementToHandle(project, getCu()));
arguments.put(JavaRefactoringDescriptorUtil.ATTRIBUTE_NAME, constantName);
arguments.put(JavaRefactoringDescriptorUtil.ATTRIBUTE_SELECTION, new Integer(start).toString() + " " + new Integer(length).toString());
arguments.put("replace", Boolean.valueOf(getReplaceAllOccurrences()).toString());
arguments.put("qualify", Boolean.valueOf(getQualifyReferencesWithDeclaringClassName()).toString());
arguments.put("visibility", new Integer(JdtFlags.getVisibilityCode(getVisibility())).toString());
ExtractConstantDescriptor descriptor= RefactoringSignatureDescriptorFactory.createExtractConstantDescriptor(project, description, comment.asString(), arguments, flags);
return descriptor;
}
private boolean getReplaceAllOccurrences() {
return ((Boolean) ReflectionUtils.getPrivateField(ExtractConstantRefactoring.class, "fReplaceAllOccurrences", this)).booleanValue();
}
private boolean getQualifyReferencesWithDeclaringClassName() {
return ((Boolean) ReflectionUtils.getPrivateField(ExtractConstantRefactoring.class, "fQualifyReferencesWithDeclaringClassName", this)).booleanValue();
}
@Override
public String getName() {
return super.getName() + (getReplaceAllOccurrences() ? " (all occurrences)" : "");
}
private void computeConstantDeclarationLocation() {
if (isDeclarationLocationComputed()) {
return;
}
FieldNode lastStaticDependency= null;
Iterator<FieldNode> decls= getContainingClassNode().getFields().iterator();
while (decls.hasNext()) {
FieldNode decl= decls.next();
if (decl.isStatic() && decl.getEnd() > 0) {
lastStaticDependency= decl;
}
}
if (lastStaticDependency == null) {
insertFirst= true;
} else {
toInsertAfter= lastStaticDependency;
}
}
/**
* @return
*/
private ClassNode getContainingClassNode() {
return ASTTools.getContainingClassNode(getCu().getModuleNode(), getSelectionStart());
}
/**
* @param b
*/
private void setTargetIsInterface(boolean b) {
ReflectionUtils.setPrivateField(ExtractConstantRefactoring.class, "fTargetIsInterface", this, true);
}
private RefactoringStatus checkSelection(IProgressMonitor pm) throws JavaModelException {
try {
pm.beginTask("", 2);
IASTFragment selectedFragment = getSelectedFragment();
if (selectedFragment == null) {
String message= RefactoringCoreMessages.ExtractConstantRefactoring_select_expression;
return RefactoringStatus.createFatalErrorStatus(message, createContext());
}
pm.worked(1);
RefactoringStatus result= new RefactoringStatus();
result.merge(checkFragment());
if (result.hasFatalError())
return result;
pm.worked(1);
return result;
} finally {
pm.done();
}
}
private RefactoringStatus checkFragment() throws JavaModelException {
RefactoringStatus result= new RefactoringStatus();
IASTFragment selectedFragment = getSelectedFragment();
result.merge(checkExpressionFragmentIsRValue(selectedFragment));
if(result.hasFatalError())
return result;
checkAllStaticFinal();
if (!selectionAllStaticFinal()) {
result.merge(RefactoringStatus
.createFatalErrorStatus(RefactoringCoreMessages.ExtractConstantRefactoring_not_load_time_constant));
}
Expression expression = selectedFragment.getAssociatedExpression();
if ((expression instanceof ConstantExpression) && ((ConstantExpression) expression).isNullExpression()) {
result.merge(RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.ExtractConstantRefactoring_null_literals));
}
return result;
}
private void checkAllStaticFinal() throws JavaModelException {
StaticFragmentChecker checker = new StaticFragmentChecker();
boolean maybeStatic = checker.mayNotBeStatic(getSelectedFragment());
ReflectionUtils.setPrivateField(ExtractConstantRefactoring.class, "fSelectionAllStaticFinal", this, maybeStatic);
ReflectionUtils.setPrivateField(ExtractConstantRefactoring.class, "fAllStaticFinalCheckPerformed", this, true);
}
private RefactoringStatus checkExpressionFragmentIsRValue(IASTFragment fragment) throws JavaModelException {
if (fragment.kind() == ASTFragmentKind.SIMPLE_EXPRESSION) {
Expression expr = fragment.getAssociatedExpression();
if (expr instanceof VariableExpression) {
VariableExpression var = (VariableExpression) expr;
if (var.getAccessedVariable() == var) {
return RefactoringStatus
.createFatalErrorStatus("Target expression is a variable declaration. Cannot extract a constant.");
}
// should also check to see if expression is on the left side of
// an assignment
}
}
return new RefactoringStatus();
}
private RefactoringStatusContext createContext() {
IJavaElement elt;
try {
elt = getCu().getElementAt(getSelectionStart());
if (elt instanceof IMember) {
return JavaStatusContext.create((IMember) elt);
}
} catch (JavaModelException e) {
GroovyCore.logException("Error finding refactoring context", e);
}
return null;
}
private IASTFragment getSelectedFragment() {
if (selectedFragment == null) {
selectedFragment = ASTTools.getSelectionFragment(getCu().getModuleNode(), getSelectionStart(), getSelectionLength());
}
return selectedFragment;
}
/**
* This method is really pretty useless unless we use the inferencing engine
*
* @return
*/
private String getConstantTypeName() {
Expression e = getSelectedFragment().getAssociatedExpression();
if (e != null) {
String name = e.getType().getNameWithoutPackage();
if (!name.equals("Object")) {
return name + " ";
}
}
return "";
}
// !! similar to ExtractTempRefactoring equivalent
@Override
public String getConstantSignaturePreview() throws JavaModelException {
String space= " ";
return getVisibility() + space + MODIFIER + space + getConstantTypeName() + space + constantName;
}
@Override
public RefactoringStatus checkConstantNameOnChange()
throws JavaModelException {
return Checks.checkConstantName(getConstantName(), getCu());
}
@Override
public String[] guessConstantNames() {
String text = getBaseNameFromExpression(getCu().getJavaProject(), getSelectedFragment(),
NamingConventions.VK_STATIC_FINAL_FIELD);
if (text == null) {
return new String[0];
}
try {
Integer.parseInt(text);
text = "_" + text;
} catch (NumberFormatException e) {
// ignore
}
return NamingConventions.suggestVariableNames(NamingConventions.VK_STATIC_FINAL_FIELD, NamingConventions.BK_NAME, text,
getCu().getJavaProject(), getContainingClassNode().isArray() ? 1 : 0, getExcludedVariableNames(), true);
}
private String[] getExcludedVariableNames() {
if (fExcludedVariableNames == null) {
HashSet<String> usedNames = new HashSet<String>();
for (ClassNode classNode : unit.getModuleNode().getClasses()) {
for (FieldNode fieldNode : classNode.getFields()) {
usedNames.add(fieldNode.getName());
}
}
fExcludedVariableNames = usedNames.toArray(new String[usedNames.size()]);
}
return fExcludedVariableNames;
}
private static final String[] KNOWN_METHOD_NAME_PREFIXES= {"get", "is", "to", "set"};
private static String getBaseNameFromExpression(IJavaProject project, IASTFragment assignedFragment, int variableKind) {
if (assignedFragment == null) {
return null;
}
String name = null;
Expression assignedExpression = assignedFragment.getAssociatedExpression();
if (assignedExpression instanceof CastExpression) {
assignedExpression = ((CastExpression) assignedFragment).getExpression();
}
// extract some kind of name if possible
String candidate = null;
if (assignedExpression instanceof ConstantExpression) {
candidate = ((ConstantExpression) assignedExpression).getText();
} else if (assignedExpression instanceof VariableExpression) {
candidate = ((VariableExpression) assignedExpression).getName();
} else if (assignedExpression instanceof ClassExpression) {
candidate = ((ClassExpression) assignedExpression).getType().getNameWithoutPackage();
} else if (assignedExpression instanceof MethodCallExpression) {
candidate = ((MethodCallExpression) assignedExpression).getMethodAsString();
} else if (assignedExpression instanceof StaticMethodCallExpression) {
candidate = ((StaticMethodCallExpression) assignedExpression).getMethod();
}
// now process the name into a good variable name
if (candidate != null) {
StringBuffer res= new StringBuffer();
boolean needsUnderscore= false;
for (int i= 0; i < candidate.length(); i++) {
char ch= candidate.charAt(i);
if (Character.isJavaIdentifierPart(ch)) {
if (res.length() == 0 && !Character.isJavaIdentifierStart(ch) || needsUnderscore) {
res.append('_');
}
res.append(ch);
needsUnderscore= false;
} else {
needsUnderscore= res.length() > 0;
}
}
if (res.length() > 0) {
name = res.toString();
}
}
// now recur through the rest of the fragment
IASTFragment next;
switch (assignedFragment.kind()) {
case PROPERTY:
case SAFE_PROPERTY:
case SPREAD_SAFE_PROPERTY:
case METHOD_POINTER:
next = ((PropertyExpressionFragment) assignedFragment).getNext();
break;
case METHOD_CALL:
next = ((MethodCallFragment) assignedFragment).getNext();
break;
case BINARY:
next = ((BinaryExpressionFragment) assignedFragment).getNext();
break;
default:
next = null;
}
if (next != null) {
name = name + "_" + getBaseNameFromExpression(project, next, variableKind);
}
if (name != null) {
for (int i= 0; i < KNOWN_METHOD_NAME_PREFIXES.length; i++) {
String curr= KNOWN_METHOD_NAME_PREFIXES[i];
if (name.startsWith(curr)) {
if (name.equals(curr)) {
return null; // don't suggest 'get' as variable name
} else if (Character.isUpperCase(name.charAt(curr.length()))) {
return name.substring(curr.length());
}
}
}
} else {
name = "CONSTANT";
}
return name;
}
@Override
public void setConstantName(String newName) {
super.setConstantName(newName);
Assert.isNotNull(newName);
constantName= newName;
}
@Override
public String getConstantName() {
return constantName;
}
private GroovyCompilationUnit getCu() {
if (unit == null) {
unit = (GroovyCompilationUnit) ReflectionUtils.getPrivateField(ExtractConstantRefactoring.class, "fCu", this);
}
return unit;
}
private int getSelectionStart() {
if (start == -1) {
start = (Integer) ReflectionUtils.getPrivateField(ExtractConstantRefactoring.class, "fSelectionStart", this);
}
return start;
}
private int getSelectionLength() {
if (length == -1) {
length = (Integer) ReflectionUtils.getPrivateField(ExtractConstantRefactoring.class, "fSelectionLength", this);
}
return length;
}
private void setSelectionLength(int newLength) {
ReflectionUtils.setPrivateField(ExtractConstantRefactoring.class, "fSelectionLength", this, newLength);
}
}