blob: e25f73ed216f0a4ec5dd13dcfd0a8fc3937fae28 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2009 University of Illinois at Urbana-Champaign and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* UIUC - Initial API and implementation
*******************************************************************************/
package org.eclipse.photran.internal.core.refactoring;
import static org.eclipse.photran.internal.core.reindenter.Reindenter.defaultIndentation;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.ltk.core.refactoring.RefactoringStatus;
import org.eclipse.ltk.core.refactoring.RefactoringStatusContext;
import org.eclipse.photran.internal.core.analysis.binding.Definition;
import org.eclipse.photran.internal.core.analysis.binding.Definition.Classification;
import org.eclipse.photran.internal.core.lexer.Terminal;
import org.eclipse.photran.internal.core.lexer.Token;
import org.eclipse.photran.internal.core.parser.ASTAccessStmtNode;
import org.eclipse.photran.internal.core.parser.ASTAssignmentStmtNode;
import org.eclipse.photran.internal.core.parser.ASTAttrSpecSeqNode;
import org.eclipse.photran.internal.core.parser.ASTCallStmtNode;
import org.eclipse.photran.internal.core.parser.ASTContainsStmtNode;
import org.eclipse.photran.internal.core.parser.ASTEntityDeclNode;
import org.eclipse.photran.internal.core.parser.ASTFunctionSubprogramNode;
import org.eclipse.photran.internal.core.parser.ASTGenericNameNode;
import org.eclipse.photran.internal.core.parser.ASTModuleNode;
import org.eclipse.photran.internal.core.parser.ASTSeparatedListNode;
import org.eclipse.photran.internal.core.parser.ASTSubroutineArgNode;
import org.eclipse.photran.internal.core.parser.ASTSubroutineSubprogramNode;
import org.eclipse.photran.internal.core.parser.ASTTypeDeclarationStmtNode;
import org.eclipse.photran.internal.core.parser.ASTTypeSpecNode;
import org.eclipse.photran.internal.core.parser.ASTVarOrFnRefNode;
import org.eclipse.photran.internal.core.parser.IASTListNode;
import org.eclipse.photran.internal.core.parser.IASTNode;
import org.eclipse.photran.internal.core.parser.IAccessId;
import org.eclipse.photran.internal.core.parser.IExpr;
import org.eclipse.photran.internal.core.refactoring.infrastructure.FortranEditorRefactoring;
import org.eclipse.photran.internal.core.reindenter.Reindenter;
import org.eclipse.photran.internal.core.reindenter.Reindenter.Strategy;
import org.eclipse.photran.internal.core.sourceform.SourceForm;
import org.eclipse.photran.internal.core.vpg.PhotranTokenRef;
/**
* Refactoring to create getter and setter subprograms for a module variable and replace variable
* accesses with calls to those subprograms.
* <p>
* This refactoring accepts a module variable declaration, makes that declaration PRIVATE, adds
* getter and setter procedures to the module, and then replaces accesses to the variable outside
* the module with calls to the getter and setter routines.
*
* @author Tim Yuvashev
* @author Jeff Overbey
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
public class EncapsulateVariableRefactoring extends FortranEditorRefactoring
{
private PhotranTokenRef selectedReference = null;
private Definition selectedTokenDef = null;
private boolean isUsedAsArgument = false;
//private PhotranTokenRef refInArgList = null;
private Set<PhotranTokenRef> allRefs = null;
private String getterName = null;
private String setterName = null;
private boolean wereMethodsCreated = false;
private boolean replaceAccessesInDeclaringModule = false;
public static final String AMBIGUOUS_DEF = Messages.EncapsulateVariableRefactoring_NoUniqueDefinition;
///////////////////////////////////////////////////////////
/// Public methods ///
/////////////////////////////////////////////////////////
public String getDefaultGetterName()
{
String capitalizedIdentName = getCapitalizedIdentName();
return "get"+capitalizedIdentName; //$NON-NLS-1$
}
public String getDefaultSetterName()
{
String capitalizedIdentName = getCapitalizedIdentName();
return "set"+capitalizedIdentName; //$NON-NLS-1$
}
@UserInputString(label="Getter method name ", defaultValueMethod="getDefaultGetterName")
public void setGetterName(String gName)
{
String parens = gName.length() < 2 ? "" : gName.substring(gName.length()-2, gName.length()); //$NON-NLS-1$
if(parens.equalsIgnoreCase("()")) //$NON-NLS-1$
getterName = gName.substring(0, gName.length()-2);
else
getterName = gName;
}
@UserInputString(label="Setter method name ", defaultValueMethod="getDefaultSetterName")
public void setSetterName(String sName)
{
String parens = sName.length() < 2 ? "" : sName.substring(sName.length()-2, sName.length()); //$NON-NLS-1$
if(parens.equalsIgnoreCase("()")) //$NON-NLS-1$
setterName = sName.substring(0, sName.length()-2);
else
setterName = sName;
}
public String getGetterName()
{
return getterName == null ? getDefaultGetterName() : getterName;
}
public String getSetterName()
{
return setterName == null ? getDefaultSetterName() : setterName;
}
@UserInputBoolean(label="Replace accesses in declaring module", defaultValue=false)
public void replaceAccessesInDeclaringModule(boolean replaceAccessesInDeclaringModule)
{
this.replaceAccessesInDeclaringModule = replaceAccessesInDeclaringModule;
}
public boolean isArgument()
{
return isUsedAsArgument;
}
@Override
public String getName()
{
return Messages.EncapsulateVariableRefactoring_Name;
}
///////////////////////////////////////////////////////////
/// Initial Precondition check ///
/////////////////////////////////////////////////////////
@Override
protected void doCheckInitialConditions(RefactoringStatus status, IProgressMonitor pm)
throws PreconditionFailure
{
ensureProjectHasRefactoringEnabled(status);
Token t = findEnclosingToken(this.astOfFileInEditor, this.selectedRegionInEditor);
if(t == null)
fail(Messages.EncapsulateVariableRefactoring_CouldNotFindToken);
selectedReference = t.getTokenRef();
Terminal term = t.getTerminal();
if(term == null || term != Terminal.T_IDENT)
fail(Messages.EncapsulateVariableRefactoring_PleaseSelectAnIdentifier);
selectedTokenDef = findUnambiguousDeclaration(t);
if(selectedTokenDef == null)
fail(AMBIGUOUS_DEF);
checkCanBeEncapsulated(selectedTokenDef);
allRefs = selectedTokenDef.findAllReferences(true);
checkForFixedFormReferences(allRefs);
}
protected void checkCanBeEncapsulated(Definition def) throws PreconditionFailure
{
if(!isDefinedInModule(def) ||
!def.getClassification().equals(Classification.VARIABLE_DECLARATION))
fail(Messages.EncapsulateVariableRefactoring_VariableNotSelected);
if(def.isParameter())
fail(Messages.EncapsulateVariableRefactoring_CannotEncapsulatePARAMETER);
if(def.isArray())
fail(Messages.EncapsulateVariableRefactoring_CannotEncapsulateArrays);
if(def.isPointer())
fail(Messages.EncapsulateVariableRefactoring_CannotEncapsulatePointers);
if(def.isTarget())
fail(Messages.EncapsulateVariableRefactoring_CannotEncapsulateTARGET);
}
protected boolean isDefinedInModule(Definition def)
{
Token t = def.getTokenRef().findTokenOrReturnNull();
if(t == null)
return false;
ASTModuleNode modNode = t.findNearestAncestor(ASTModuleNode.class);
return modNode != null;
}
protected void checkForFixedFormReferences(Set<PhotranTokenRef> refs) throws PreconditionFailure
{
for (PhotranTokenRef ref : refs)
checkForFixedForm(ref.getFile());
}
protected void checkForFixedForm(IFile file) throws PreconditionFailure
{
if (SourceForm.isFixedForm(file) && !FIXED_FORM_REFACTORING_ENABLED)
{
fail(
Messages.bind(
Messages.EncapsulateVariableRefactoring_CannotRefactorFixedFormFile,
file.getName()));
}
}
///////////////////////////////////////////////////////////
/// Final Precondition check ///
/////////////////////////////////////////////////////////
@Override
protected void doCheckFinalConditions(RefactoringStatus status, IProgressMonitor pm)
throws PreconditionFailure
{
checkForConflictingBindings(pm,
new ConflictingBindingErrorHandler(status),
selectedTokenDef,
allRefs,
getGetterName(),
getSetterName());
try
{
Token varDefTok = declarationToken();
ASTModuleNode declaringModule = varDefTok.findNearestAncestor(ASTModuleNode.class);
if (declaringModule == null) throw new IllegalStateException();
IFile defFile = varDefTok.getLogicalFile();
getVPG().acquirePermanentAST(defFile);
for (IFile file : filesIn(allRefs))
{
for (PhotranTokenRef ref : allRefs)
{
if (ref.getFile().equals(file))
{
Token t = ref.findTokenOrReturnNull();
if(t == null)
fail(Messages.EncapsulateVariableRefactoring_CouldNotFindTokenForVarRef);
if(!isUsedAsArgument)
detectIfUsedAsArgument(t, status);
if(replaceAccessesInDeclaringModule || !isInModule(t, declaringModule))
replaceWithGetOrSet(t, status);
}
}
if (!file.equals(defFile))
this.addChangeFromModifiedAST(file, pm);
}
this.addChangeFromModifiedAST(defFile, pm);
getVPG().releaseAST(defFile);
}
finally
{
getVPG().releaseAllASTs();
}
}
private Set<IFile> filesIn(Set<PhotranTokenRef> refs)
{
Set<IFile> result = new HashSet<IFile>(64);
for (PhotranTokenRef r : refs)
result.add(r.getFile());
return result;
}
private boolean isInModule(Token t, ASTModuleNode m)
{
return t.findNearestAncestor(ASTModuleNode.class) == m;
}
private Token declarationToken() throws PreconditionFailure
{
Token varDefTok = selectedTokenDef.getTokenRef().findTokenOrReturnNull();
if(varDefTok == null)
fail(Messages.EncapsulateVariableRefactoring_CouldNotFindTokenForVarDef);
return varDefTok;
}
protected void detectIfUsedAsArgument(Token t, RefactoringStatus status) throws PreconditionFailure
{
//If reference is used as a parameter, then it has to be inside this node
ASTSubroutineArgNode subNode = t.findNearestAncestor(ASTSubroutineArgNode.class);
if(subNode != null)
{
if(!isUsedAsArgument) //No need to keep re-setting values after one
//instance was found
{
String message =
Messages.bind(
Messages.EncapsulateVariableRefactoring_WarningFunctionArgument,
t.getPhysicalFile(),
t.getLine());
RefactoringStatusContext context = createContext(t.getTokenRef()); // Highlights problematic definition in file
status.addWarning(message, context);
isUsedAsArgument = true;
}
}
}
protected void replaceWithGetOrSet(Token t, RefactoringStatus status) throws PreconditionFailure
{
if(isTokenRead(t))
{
replaceWithGetter(t);
if(!wereMethodsCreated)
{
setGetterAndSetter();
wereMethodsCreated = true;
}
}
else if(isTokenWrittenTo(t))
{
replaceWithSetter(t);
if(!wereMethodsCreated)
{
setGetterAndSetter();
wereMethodsCreated = true;
}
}
else //Neither written nor read (i.e. Access declaration (private,public))
{
String message =
Messages.bind(
Messages.EncapsulateVariableRefactoring_WarningWillNotChangeReference,
t.getPhysicalFile(),
t.getLine());
RefactoringStatusContext context = createContext(t.getTokenRef());
status.addWarning(message, context);
}
}
protected boolean isTokenRead(Token t)
{
ASTVarOrFnRefNode expressionNode = t.findNearestAncestor(ASTVarOrFnRefNode.class);
if(expressionNode == null)
return false;
return true;
}
protected void replaceWithGetter(Token t) throws PreconditionFailure
{
checkIfCanEncapsulateWithGetter(t);
IExpr newExpr = parseLiteralExpression(getGetterName() + "()"); //$NON-NLS-1$
newExpr.findFirstToken().setWhiteBefore(""); //$NON-NLS-1$
IExpr oldExpr = t.findNearestAncestor(IExpr.class);
oldExpr.replaceWith(newExpr);
//newExpr.setParent(oldExpr.getParent());
}
protected void checkIfCanEncapsulateWithGetter(Token t) throws PreconditionFailure
{
IExpr expr = t.findNearestAncestor(IExpr.class);
if(expr == null)
{
fail(
Messages.bind(
Messages.EncapsulateVariableRefactoring_NotAnExpression,
t.getPhysicalFile(),
t.getLine()));
}
}
protected void setGetterAndSetter() throws PreconditionFailure
{
Token varDefTok = declarationToken();
ASTModuleNode mod = varDefTok.findNearestAncestor(ASTModuleNode.class);
IASTListNode lst = mod.getBody();
addPrivateStatement(varDefTok, lst);
//TODO: Check for conflict names of functions
addGetterFunction(selectedTokenDef, lst);
addSetterFunction(selectedTokenDef, lst);
}
//TODO: Possibly re-factor this function (too long?)
protected void addPrivateStatement(Token varDefTok, IASTListNode lst) throws PreconditionFailure
{
ASTTypeDeclarationStmtNode typeDec = varDefTok.findNearestAncestor(ASTTypeDeclarationStmtNode.class);
for(int i = 0; i < lst.size(); i++)
{
IASTNode node = (IASTNode)lst.get(i);
if(node instanceof ASTTypeDeclarationStmtNode)
{
ASTTypeDeclarationStmtNode possibleTypeDec = (ASTTypeDeclarationStmtNode)node;
if(possibleTypeDec != null && possibleTypeDec == typeDec)
{
ASTTypeDeclarationStmtNode newDeclNode = removePublicDeclarationIfNeeded(varDefTok, possibleTypeDec, lst);
ASTAccessStmtNode newAccessNode =
(ASTAccessStmtNode)parseLiteralStatement("private :: " + varDefTok.getText() + EOL); //$NON-NLS-1$
newAccessNode.setParent(lst);
if(newDeclNode != null)
{
lst.insertAfter(newDeclNode, newAccessNode);
Reindenter.reindent(newDeclNode,
getVPG().acquireTransientAST(varDefTok.getLogicalFile()),
Strategy.REINDENT_EACH_LINE);
}
else
lst.insertAfter(possibleTypeDec, newAccessNode);
Reindenter.reindent(newAccessNode,
getVPG().acquireTransientAST(varDefTok.getLogicalFile()),
Strategy.REINDENT_EACH_LINE);
break;
}
}
}
}
protected ASTTypeDeclarationStmtNode removePublicDeclarationIfNeeded(
Token varDefTok,
ASTTypeDeclarationStmtNode declNode,
IASTListNode lst)
{
if(declNode.getAttrSpecSeq() != null)
{
if(containsPublicInDecl(declNode.getAttrSpecSeq()))
{
return redeclareVariable(varDefTok, declNode);
}
}
boolean wasRemoved = false;
for(int i = 0; i < lst.size() && !wasRemoved; i++)
{
if(lst.get(i) instanceof ASTAccessStmtNode)
{
ASTAccessStmtNode accessNode = (ASTAccessStmtNode)lst.get(i);
wasRemoved = removeTokenFromPublicVarDecl(accessNode, varDefTok);
if(wasRemoved && accessNode.getAccessIdList().size() <= 0)
{
lst.remove(accessNode);
break;
}
}
}
return null;
}
/* (non-Javadoc)
* @see org.eclipse.photran.internal.core.refactoring.infrastructure.AbstractFortranRefactoring#doCreateChange(org.eclipse.core.runtime.IProgressMonitor)
*/
@Override
protected void doCreateChange(IProgressMonitor pm) throws CoreException,
OperationCanceledException
{
}
protected boolean isTokenWrittenTo(Token t)
{
ASTAssignmentStmtNode assign = t.findNearestAncestor(ASTAssignmentStmtNode.class);
if(assign == null)
return false;
return true;
}
protected void replaceWithSetter(Token t)
{
String whiteBeforeOld = t.getWhiteBefore();
ASTAssignmentStmtNode oldAssignNode = t.findNearestAncestor(ASTAssignmentStmtNode.class);
//String rhsString = oldAssignNode.getRhs().toString().trim();
String setterString = "call " + getSetterName() + "()"; //$NON-NLS-1$ //$NON-NLS-2$
ASTCallStmtNode newCallNode = (ASTCallStmtNode)parseLiteralStatement(setterString);
newCallNode.findFirstToken().setWhiteBefore(whiteBeforeOld);
IASTListNode<ASTSubroutineArgNode> argList = convertToArguments(oldAssignNode);
argList.setParent(newCallNode);
newCallNode.setArgList(argList);
oldAssignNode.replaceWith(newCallNode);
//newCallNode.setParent(oldAssignNode.getParent());
}
protected IASTListNode<ASTSubroutineArgNode> convertToArguments(ASTAssignmentStmtNode oldAssignNode)
{
ASTSubroutineArgNode args = new ASTSubroutineArgNode();
Token tok = oldAssignNode.getRhs().findFirstToken();
tok.setWhiteBefore(""); //$NON-NLS-1$
args.setExpr(oldAssignNode.getRhs());
oldAssignNode.getRhs().setParent(args);
ArrayList<ASTSubroutineArgNode> argList = new ArrayList<ASTSubroutineArgNode>();
argList.add(args);
ASTSeparatedListNode<ASTSubroutineArgNode> sepList = new ASTSeparatedListNode<ASTSubroutineArgNode>(null, argList, true);
args.setParent(sepList);
return sepList;
}
protected int findOrCreateContainsIndex(IASTListNode lst)
{
boolean isFound = false;
int i = 0;
for(; i < lst.size(); i++)
{
IASTNode node = (IASTNode)lst.get(i);
if(node instanceof ASTContainsStmtNode)
{
isFound = true;
break;
}
}
if(!isFound)
{
ASTContainsStmtNode containsStmt = createContainsStmt();
lst.add(containsStmt);
i = lst.size() - 1;
}
return i;
}
protected void addGetterFunction(Definition def, IASTListNode lst)
{
int index = findOrCreateContainsIndex(lst);
ASTFunctionSubprogramNode funNode = createGetterFunction(def);
funNode.setParent(lst);
lst.insertAfter(lst.get(index), funNode);
Reindenter.reindent(funNode,
getVPG().acquireTransientAST(def.getTokenRef().getFile()),
Strategy.SHIFT_ENTIRE_BLOCK);
}
protected void addSetterFunction(Definition def, IASTListNode lst)
{
int index = findOrCreateContainsIndex(lst);
ASTSubroutineSubprogramNode funNode = createSetterFunction(def);
funNode.setParent(lst);
lst.insertAfter(lst.get(index), funNode);
Reindenter.reindent(funNode,
getVPG().acquireTransientAST(def.getTokenRef().getFile()),
Strategy.SHIFT_ENTIRE_BLOCK);
}
protected ASTFunctionSubprogramNode createGetterFunction(Definition def)
{
String type = def.getType().toString();
String getterFunction = type + " function " + getGetterName() + "()" + EOL + //$NON-NLS-1$ //$NON-NLS-2$
defaultIndentation() + "implicit none" + EOL + //$NON-NLS-1$
defaultIndentation() + getGetterName() + " = " + def.getTokenRef().getText() +EOL + //$NON-NLS-1$
"end function" + EOL; //$NON-NLS-1$
ASTFunctionSubprogramNode newFunNode = (ASTFunctionSubprogramNode)parseLiteralProgramUnit(getterFunction);
return newFunNode;
}
protected ASTSubroutineSubprogramNode createSetterFunction(Definition def)
{
String type = def.getType().toString();
String valueName = "value"; //$NON-NLS-1$
String setterFunction = "subroutine " + getSetterName() + "(" + valueName + ")" + EOL + //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
defaultIndentation() + "implicit none" + EOL + //$NON-NLS-1$
defaultIndentation() + type + ", intent(in) :: " + valueName + EOL + //$NON-NLS-1$
defaultIndentation() + def.getTokenRef().getText() +" = " + valueName + EOL + //$NON-NLS-1$
"end subroutine" + EOL; //$NON-NLS-1$
ASTSubroutineSubprogramNode newSubNode = (ASTSubroutineSubprogramNode)parseLiteralProgramUnit(setterFunction);
return newSubNode;
}
protected boolean containsPublicInDecl(IASTListNode lst)
{
for(int i = 0; i < lst.size(); i++)
{
if(lst.get(i) instanceof ASTAttrSpecSeqNode)
{
ASTAttrSpecSeqNode secNode = (ASTAttrSpecSeqNode)lst.get(i);
if(secNode.getAttrSpec().getAccessSpec().isPublic())
return true;
}
}
return false;
}
protected ASTTypeDeclarationStmtNode createNewDeclaration(Token varDefTok, ASTTypeSpecNode typeSpec)
{
String newDecl = findUnambiguousDeclaration(varDefTok).getType().toString() + " :: " + varDefTok.getText(); //$NON-NLS-1$
ASTTypeDeclarationStmtNode declNode = (ASTTypeDeclarationStmtNode)parseLiteralStatement(newDecl);
return declNode;
}
protected ASTTypeDeclarationStmtNode removeAllAndRedeclare(Token varDefTok, ASTTypeDeclarationStmtNode oldDeclNode)
{
ASTTypeDeclarationStmtNode newDeclNode = createNewDeclaration(varDefTok, oldDeclNode.getTypeSpec());
oldDeclNode.replaceWith(newDeclNode);
//newDeclNode.setParent(oldDeclNode.getParent());
return newDeclNode;
}
protected ASTTypeDeclarationStmtNode removeAndRedeclare(Token varDefTok, ASTTypeDeclarationStmtNode oldDeclNode)
{
ASTTypeDeclarationStmtNode newDeclNode = createNewDeclaration(varDefTok, oldDeclNode.getTypeSpec());
IASTListNode<ASTEntityDeclNode> lst = oldDeclNode.getEntityDeclList();
for(ASTEntityDeclNode declNode : lst)
{
if(declNode.findFirstToken() == varDefTok)
{
lst.remove(declNode);
break;
}
}
newDeclNode.setParent(oldDeclNode.getParent());
IASTListNode parent = (IASTListNode)oldDeclNode.getParent();
parent.insertAfter(oldDeclNode, newDeclNode);
return newDeclNode;
}
protected ASTTypeDeclarationStmtNode redeclareVariable(Token varDefTok, ASTTypeDeclarationStmtNode declNode)
{
IASTListNode declList = declNode.getEntityDeclList();
if(declList.size() == 1)
return removeAllAndRedeclare(varDefTok, declNode);
else
return removeAndRedeclare(varDefTok, declNode);
}
protected boolean removeTokenFromPublicVarDecl(ASTAccessStmtNode accessNode, Token varDefTok)
{
if(accessNode.getAccessSpec().isPublic())
{
IASTListNode<IAccessId> varList = accessNode.getAccessIdList();
for(IAccessId id : varList)
{
if(id instanceof ASTGenericNameNode)
{
ASTGenericNameNode name = (ASTGenericNameNode)id;
String nameLabel = name.findFirstToken().getText();
if(nameLabel.equalsIgnoreCase(varDefTok.getText()))
{
varList.remove(id);
return true;
}
}
}
}
return false;
}
///////////////////////////////////////////////////////////
/// Private methods ///
/////////////////////////////////////////////////////////
private String getCapitalizedIdentName()
{
String identName = selectedReference.getText();
String fstLetter = identName.substring(0,1);
String upCase = fstLetter.toUpperCase();
String capitalizedIdentName = upCase.concat(identName.substring(1));
return capitalizedIdentName;
}
///////////////////////////////////////////////////////////
/// Conflict error hanlder class ///
/////////////////////////////////////////////////////////
private final class ConflictingBindingErrorHandler implements IConflictingBindingCallback
{
private final RefactoringStatus status;
private ConflictingBindingErrorHandler(RefactoringStatus status) { this.status = status; }
public void addConflictError(List<Conflict> conflictingDef)
{
for(Conflict conflict : conflictingDef)
{
String msg =
Messages.bind(
Messages.EncapsulateVariableRefactoring_NameConflicts,
conflict.name,
getVPG().getDefinitionFor(conflict.tokenRef));
RefactoringStatusContext context = createContext(conflict.tokenRef); // Highlights problematic definition
status.addError(msg, context);
}
}
public void addConflictWarning(List<Conflict> conflictingDef)
{
for(Conflict conflict : conflictingDef)
{
String msg =
Messages.bind(
Messages.EncapsulateVariableRefactoring_NameMightConflict,
conflict.name);
RefactoringStatusContext context = createContext(conflict.tokenRef); // Highlights problematic definition
status.addWarning(msg, context);
}
}
public void addReferenceWillChangeError(String newName, Token reference)
{
// The entity with the new name will shadow the definition to which this binding resolves
/*status.addError("Changing the name to \"" + newName + "\""
+ " would change the meaning of \"" + reference.getText() + "\" on line " + reference.getLine()
+ " in " + reference.getTokenRef().getFilename(),
createContext(reference)); // Highlight problematic reference*/
}
}
}