[Pydev-cvs] org.python.pydev.refactoring/src/org/python/pydev/refactoring/coderefactoring/extractme
Brought to you by:
fabioz
Update of /cvsroot/pydev/org.python.pydev.refactoring/src/org/python/pydev/refactoring/coderefactoring/extractmethod/edit In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv21605/src/org/python/pydev/refactoring/coderefactoring/extractmethod/edit Modified Files: ExtractMethodEdit.java ExtractCallEdit.java ParameterReturnDeduce.java Log Message: Synching to latest changes: Pydev <ul> <li><strong>Editor</strong>: Cursor settings no longer overridden</li> <li><strong>Code-completion</strong>: If __all__ is defined with runtime elements (and not only in a single assign statement), it's ignored for code-completion purposes</li> <li><strong>Debugger</strong>: Pythonpath the same in debug and regular modes (sys.path[0] is the same directory as the file run)</li> <li><strong>Debugger</strong>: Persist choices done in the debugger when files from the debugger are not found</li> <li><strong>Interpreter config</strong>: "email" automatically added to the "forced builtins"</li> <li><strong>Parser</strong>: Correctly recognizing absolute import with 3 or more levels</li> <li><strong>Syntax check</strong>: Option to do only on active editor</li> </ul> Also: tabs changed for spaces Index: ExtractMethodEdit.java =================================================================== RCS file: /cvsroot/pydev/org.python.pydev.refactoring/src/org/python/pydev/refactoring/coderefactoring/extractmethod/edit/ExtractMethodEdit.java,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** ExtractMethodEdit.java 20 Oct 2007 19:31:01 -0000 1.5 --- ExtractMethodEdit.java 27 Sep 2008 20:00:46 -0000 1.6 *************** *** 34,149 **** public class ExtractMethodEdit extends AbstractInsertEdit { ! private String methodName; ! private ModuleAdapter parsedSelection; ! private int offsetStrategy; ! private AbstractScopeNode<?> scopeAdapter; ! private List<String> parameters; ! private List<String> returnVariables; ! private Map<String, String> renamedVariables; ! public ExtractMethodEdit(ExtractMethodRequest req) { ! super(req); ! this.methodName = req.getMethodName(); ! this.scopeAdapter = req.getScopeAdapter(); ! this.parsedSelection = req.getParsedSelection(); ! this.offsetStrategy = req.getOffsetStrategy(); ! this.parameters = req.getParameters(); ! this.returnVariables = req.getReturnVariables(); ! this.renamedVariables = req.getRenamedVariables(); ! } ! @Override ! protected SimpleNode getEditNode() { ! List<stmtType> body = initExtractedBody(); ! List<exprType> argsList = initExtractedMethodArguments(); ! addReturnValue(body); ! FunctionDef extractedMethod = initExtractedMethod(body, argsList); ! applyRenamedVariables(extractedMethod); ! return extractedMethod; ! } ! private FunctionDef initExtractedMethod(List<stmtType> body, List<exprType> argsList) { ! argumentsType args = new argumentsType(argsList.toArray(new exprType[0]), null, null, null); ! FunctionDef extractedMethod = new FunctionDef(new NameTok(methodName, NameTok.FunctionName), args, body.toArray(new stmtType[0]), ! null); ! return extractedMethod; ! } ! private List<exprType> initExtractedMethodArguments() { ! List<exprType> argsList = new ArrayList<exprType>(); ! if (this.scopeAdapter instanceof FunctionDefAdapter) { ! IASTNodeAdapter<? extends SimpleNode> parentScopeAdapter = scopeAdapter.getParent(); ! while (parentScopeAdapter instanceof FunctionDef) { ! parentScopeAdapter = scopeAdapter.getParent(); ! } ! if (parentScopeAdapter instanceof IClassDefAdapter) { ! argsList.add(new Name("self", Name.Load)); ! } ! } ! for (String variable : this.parameters) { ! argsList.add(new Name(variable, Name.Param)); ! } ! return argsList; ! } ! private List<stmtType> initExtractedBody() { ! stmtType[] extractBody = parsedSelection.getASTNode().body; ! List<stmtType> body = new ArrayList<stmtType>(); ! for (stmtType stmt : extractBody) { ! body.add(stmt); ! } ! return body; ! } ! private void applyRenamedVariables(FunctionDef extractedMethod) { ! if (renamedVariables.size() > 0) { ! LocalVarRenameVisitor renameVisitor = new LocalVarRenameVisitor(this.newLineDelim); ! renameVisitor.setRenameMap(renamedVariables); ! try { ! extractedMethod.accept(renameVisitor); ! } catch (Exception e) { ! } ! } ! } ! private void addReturnValue(List<stmtType> body) { ! List<exprType> returnList = new ArrayList<exprType>(); ! for (String variable : this.returnVariables) { ! returnList.add(new Name(variable, Name.Load)); ! } ! exprType returnValue = null; ! if (returnList.size() == 1) { ! returnValue = returnList.get(0); ! } else if (returnList.size() > 1) { ! returnValue = new Tuple(returnList.toArray(new exprType[0]), Tuple.Load); ! } else if (body.size() == 1) { ! // return expression as-is (note: body must be cleared) ! if (body.get(0) instanceof Expr) { ! Expr expression = (Expr) body.get(0); ! returnValue = expression.value; ! body.clear(); ! } ! } ! if (returnValue != null) { ! body.add(new Return(returnValue)); ! } ! } ! @Override ! public int getOffsetStrategy() { ! return offsetStrategy; ! } } --- 34,149 ---- public class ExtractMethodEdit extends AbstractInsertEdit { ! private String methodName; ! private ModuleAdapter parsedSelection; ! private int offsetStrategy; ! private AbstractScopeNode<?> scopeAdapter; ! private List<String> parameters; ! private List<String> returnVariables; ! private Map<String, String> renamedVariables; ! public ExtractMethodEdit(ExtractMethodRequest req) { ! super(req); ! this.methodName = req.getMethodName(); ! this.scopeAdapter = req.getScopeAdapter(); ! this.parsedSelection = req.getParsedSelection(); ! this.offsetStrategy = req.getOffsetStrategy(); ! this.parameters = req.getParameters(); ! this.returnVariables = req.getReturnVariables(); ! this.renamedVariables = req.getRenamedVariables(); ! } ! @Override ! protected SimpleNode getEditNode() { ! List<stmtType> body = initExtractedBody(); ! List<exprType> argsList = initExtractedMethodArguments(); ! addReturnValue(body); ! FunctionDef extractedMethod = initExtractedMethod(body, argsList); ! applyRenamedVariables(extractedMethod); ! return extractedMethod; ! } ! private FunctionDef initExtractedMethod(List<stmtType> body, List<exprType> argsList) { ! argumentsType args = new argumentsType(argsList.toArray(new exprType[0]), null, null, null); ! FunctionDef extractedMethod = new FunctionDef(new NameTok(methodName, NameTok.FunctionName), args, body.toArray(new stmtType[0]), ! null); ! return extractedMethod; ! } ! private List<exprType> initExtractedMethodArguments() { ! List<exprType> argsList = new ArrayList<exprType>(); ! if (this.scopeAdapter instanceof FunctionDefAdapter) { ! IASTNodeAdapter<? extends SimpleNode> parentScopeAdapter = scopeAdapter.getParent(); ! while (parentScopeAdapter instanceof FunctionDef) { ! parentScopeAdapter = scopeAdapter.getParent(); ! } ! if (parentScopeAdapter instanceof IClassDefAdapter) { ! argsList.add(new Name("self", Name.Load)); ! } ! } ! for (String variable : this.parameters) { ! argsList.add(new Name(variable, Name.Param)); ! } ! return argsList; ! } ! private List<stmtType> initExtractedBody() { ! stmtType[] extractBody = parsedSelection.getASTNode().body; ! List<stmtType> body = new ArrayList<stmtType>(); ! for (stmtType stmt : extractBody) { ! body.add(stmt); ! } ! return body; ! } ! private void applyRenamedVariables(FunctionDef extractedMethod) { ! if (renamedVariables.size() > 0) { ! LocalVarRenameVisitor renameVisitor = new LocalVarRenameVisitor(this.newLineDelim); ! renameVisitor.setRenameMap(renamedVariables); ! try { ! extractedMethod.accept(renameVisitor); ! } catch (Exception e) { ! } ! } ! } ! private void addReturnValue(List<stmtType> body) { ! List<exprType> returnList = new ArrayList<exprType>(); ! for (String variable : this.returnVariables) { ! returnList.add(new Name(variable, Name.Load)); ! } ! exprType returnValue = null; ! if (returnList.size() == 1) { ! returnValue = returnList.get(0); ! } else if (returnList.size() > 1) { ! returnValue = new Tuple(returnList.toArray(new exprType[0]), Tuple.Load); ! } else if (body.size() == 1) { ! // return expression as-is (note: body must be cleared) ! if (body.get(0) instanceof Expr) { ! Expr expression = (Expr) body.get(0); ! returnValue = expression.value; ! body.clear(); ! } ! } ! if (returnValue != null) { ! body.add(new Return(returnValue)); ! } ! } ! @Override ! public int getOffsetStrategy() { ! return offsetStrategy; ! } } Index: ParameterReturnDeduce.java =================================================================== RCS file: /cvsroot/pydev/org.python.pydev.refactoring/src/org/python/pydev/refactoring/coderefactoring/extractmethod/edit/ParameterReturnDeduce.java,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** ParameterReturnDeduce.java 20 Oct 2007 19:31:01 -0000 1.6 --- ParameterReturnDeduce.java 27 Sep 2008 20:00:46 -0000 1.7 *************** *** 22,168 **** public class ParameterReturnDeduce { ! private List<String> parameters; ! private Set<String> returns; ! private AbstractScopeNode<?> scopeAdapter; ! private ITextSelection selection; ! private ModuleAdapter moduleAdapter; ! public ParameterReturnDeduce(AbstractScopeNode<?> scope, ITextSelection selection, ModuleAdapter moduleAdapter) { ! this.scopeAdapter = scope; ! this.selection = selection; ! this.parameters = new ArrayList<String>(); ! this.returns = new HashSet<String>(); ! this.moduleAdapter = moduleAdapter; ! deduce(); ! } ! private void deduce() { ! List<SimpleAdapter> before = new ArrayList<SimpleAdapter>(); ! List<SimpleAdapter> after = new ArrayList<SimpleAdapter>(); ! ModuleAdapter module = scopeAdapter.getModule(); ! List<SimpleAdapter> selected = module.getWithinSelection(this.selection, scopeAdapter.getUsedVariables()); ! extractBeforeAfterVariables(selected, before, after); ! deduceParameters(before, selected); ! deduceReturns(after, selected); ! } ! /** ! * Needed fix: only add it if it is not a global (unless it shadows a global) ! */ ! private void deduceParameters(List<SimpleAdapter> before, List<SimpleAdapter> selected) { ! Set<String> globarVarNames = new HashSet<String>(moduleAdapter.getGlobarVarNames()); ! ! for (SimpleAdapter adapter : before) { ! if (adapter.getASTNode() instanceof Name) { ! Name variable = (Name) adapter.getASTNode(); ! if(globarVarNames.contains(variable.id)){ ! continue; ! } ! if (isUsed(variable.id, selected)) { ! if (!parameters.contains(variable.id)) { ! parameters.add(variable.id); ! } ! } ! } ! } ! } ! private void deduceReturns(List<SimpleAdapter> after, List<SimpleAdapter> selected) { ! for (SimpleAdapter adapter : after) { ! if (adapter.getASTNode() instanceof Name) { ! Name variable = (Name) adapter.getASTNode(); ! if (isStored(variable.id, selected)) { ! returns.add(variable.id); ! } ! } ! } ! } ! private void extractBeforeAfterVariables(List<SimpleAdapter> selectedVariables, List<SimpleAdapter> before, List<SimpleAdapter> after) { ! List<SimpleAdapter> scopeVariables = scopeAdapter.getUsedVariables(); ! if (selectedVariables.size() < 1) ! return; ! SimpleAdapter firstSelectedVariable = selectedVariables.get(0); ! SimpleAdapter lastSelectedVariable = selectedVariables.get(selectedVariables.size() - 1); ! for (SimpleAdapter adapter : scopeVariables) { ! if (isBeforeSelectedLine(firstSelectedVariable, adapter) || isBeforeOnSameLine(firstSelectedVariable, adapter)) { ! before.add(adapter); ! ! } else if (isAfterSelectedLine(lastSelectedVariable, adapter) || isAfterOnSameLine(lastSelectedVariable, adapter)) { ! after.add(adapter); ! } ! } ! } ! private boolean isAfterOnSameLine(SimpleAdapter lastSelectedVariable, SimpleAdapter adapter) { ! return adapter.getNodeFirstLine() == lastSelectedVariable.getNodeFirstLine() ! && (adapter.getNodeIndent() > lastSelectedVariable.getNodeIndent()); ! } ! private boolean isAfterSelectedLine(SimpleAdapter lastSelectedVariable, SimpleAdapter adapter) { ! return adapter.getNodeFirstLine() > lastSelectedVariable.getNodeFirstLine(); ! } ! private boolean isBeforeOnSameLine(SimpleAdapter firstSelectedVariable, SimpleAdapter adapter) { ! return adapter.getNodeFirstLine() == firstSelectedVariable.getNodeFirstLine() ! && (adapter.getNodeIndent() < firstSelectedVariable.getNodeIndent()); ! } ! private boolean isBeforeSelectedLine(SimpleAdapter firstSelectedVariable, SimpleAdapter adapter) { ! return adapter.getNodeFirstLine() < firstSelectedVariable.getNodeFirstLine(); ! } ! /** ! * Fix (fabioz): to check if it is used, it must be in a load context ! */ ! private boolean isUsed(String var, List<SimpleAdapter> scopeVariables) { ! for (SimpleAdapter adapter : scopeVariables) { ! SimpleNode astNode = adapter.getASTNode(); ! if (astNode instanceof Name) { ! Name scopeVar = (Name) astNode; ! if ((scopeVar.ctx == Name.Load || scopeVar.ctx == Name.AugLoad) && scopeVar.id.equals(var)) { ! return true; ! } ! } ! } ! return false; ! } ! private boolean isStored(String var, List<SimpleAdapter> scopeVariables) { ! boolean isStored = false; ! // must traverse all variables, because a ! // variable may be used in other context! ! for (SimpleAdapter adapter : scopeVariables) { ! SimpleNode astNode = adapter.getASTNode(); ! if (astNode instanceof Name) { ! Name scopeVar = (Name) astNode; ! if (scopeVar.id.equals(var)) { ! isStored = (scopeVar.ctx == Name.Store || scopeVar.ctx == Name.AugStore); ! } ! } ! if (isStored) ! break; ! } ! return isStored; ! } ! public List<String> getParameters() { ! return this.parameters; ! } ! public List<String> getReturns() { ! return new ArrayList<String>(this.returns); ! } } --- 22,168 ---- public class ParameterReturnDeduce { ! private List<String> parameters; ! private Set<String> returns; ! private AbstractScopeNode<?> scopeAdapter; ! private ITextSelection selection; ! private ModuleAdapter moduleAdapter; ! public ParameterReturnDeduce(AbstractScopeNode<?> scope, ITextSelection selection, ModuleAdapter moduleAdapter) { ! this.scopeAdapter = scope; ! this.selection = selection; ! this.parameters = new ArrayList<String>(); ! this.returns = new HashSet<String>(); ! this.moduleAdapter = moduleAdapter; ! deduce(); ! } ! private void deduce() { ! List<SimpleAdapter> before = new ArrayList<SimpleAdapter>(); ! List<SimpleAdapter> after = new ArrayList<SimpleAdapter>(); ! ModuleAdapter module = scopeAdapter.getModule(); ! List<SimpleAdapter> selected = module.getWithinSelection(this.selection, scopeAdapter.getUsedVariables()); ! extractBeforeAfterVariables(selected, before, after); ! deduceParameters(before, selected); ! deduceReturns(after, selected); ! } ! /** ! * Needed fix: only add it if it is not a global (unless it shadows a global) ! */ ! private void deduceParameters(List<SimpleAdapter> before, List<SimpleAdapter> selected) { ! Set<String> globarVarNames = new HashSet<String>(moduleAdapter.getGlobarVarNames()); ! ! for (SimpleAdapter adapter : before) { ! if (adapter.getASTNode() instanceof Name) { ! Name variable = (Name) adapter.getASTNode(); ! if(globarVarNames.contains(variable.id)){ ! continue; ! } ! if (isUsed(variable.id, selected)) { ! if (!parameters.contains(variable.id)) { ! parameters.add(variable.id); ! } ! } ! } ! } ! } ! private void deduceReturns(List<SimpleAdapter> after, List<SimpleAdapter> selected) { ! for (SimpleAdapter adapter : after) { ! if (adapter.getASTNode() instanceof Name) { ! Name variable = (Name) adapter.getASTNode(); ! if (isStored(variable.id, selected)) { ! returns.add(variable.id); ! } ! } ! } ! } ! private void extractBeforeAfterVariables(List<SimpleAdapter> selectedVariables, List<SimpleAdapter> before, List<SimpleAdapter> after) { ! List<SimpleAdapter> scopeVariables = scopeAdapter.getUsedVariables(); ! if (selectedVariables.size() < 1) ! return; ! SimpleAdapter firstSelectedVariable = selectedVariables.get(0); ! SimpleAdapter lastSelectedVariable = selectedVariables.get(selectedVariables.size() - 1); ! for (SimpleAdapter adapter : scopeVariables) { ! if (isBeforeSelectedLine(firstSelectedVariable, adapter) || isBeforeOnSameLine(firstSelectedVariable, adapter)) { ! before.add(adapter); ! ! } else if (isAfterSelectedLine(lastSelectedVariable, adapter) || isAfterOnSameLine(lastSelectedVariable, adapter)) { ! after.add(adapter); ! } ! } ! } ! private boolean isAfterOnSameLine(SimpleAdapter lastSelectedVariable, SimpleAdapter adapter) { ! return adapter.getNodeFirstLine() == lastSelectedVariable.getNodeFirstLine() ! && (adapter.getNodeIndent() > lastSelectedVariable.getNodeIndent()); ! } ! private boolean isAfterSelectedLine(SimpleAdapter lastSelectedVariable, SimpleAdapter adapter) { ! return adapter.getNodeFirstLine() > lastSelectedVariable.getNodeFirstLine(); ! } ! private boolean isBeforeOnSameLine(SimpleAdapter firstSelectedVariable, SimpleAdapter adapter) { ! return adapter.getNodeFirstLine() == firstSelectedVariable.getNodeFirstLine() ! && (adapter.getNodeIndent() < firstSelectedVariable.getNodeIndent()); ! } ! private boolean isBeforeSelectedLine(SimpleAdapter firstSelectedVariable, SimpleAdapter adapter) { ! return adapter.getNodeFirstLine() < firstSelectedVariable.getNodeFirstLine(); ! } ! /** ! * Fix (fabioz): to check if it is used, it must be in a load context ! */ ! private boolean isUsed(String var, List<SimpleAdapter> scopeVariables) { ! for (SimpleAdapter adapter : scopeVariables) { ! SimpleNode astNode = adapter.getASTNode(); ! if (astNode instanceof Name) { ! Name scopeVar = (Name) astNode; ! if ((scopeVar.ctx == Name.Load || scopeVar.ctx == Name.AugLoad) && scopeVar.id.equals(var)) { ! return true; ! } ! } ! } ! return false; ! } ! private boolean isStored(String var, List<SimpleAdapter> scopeVariables) { ! boolean isStored = false; ! // must traverse all variables, because a ! // variable may be used in other context! ! for (SimpleAdapter adapter : scopeVariables) { ! SimpleNode astNode = adapter.getASTNode(); ! if (astNode instanceof Name) { ! Name scopeVar = (Name) astNode; ! if (scopeVar.id.equals(var)) { ! isStored = (scopeVar.ctx == Name.Store || scopeVar.ctx == Name.AugStore); ! } ! } ! if (isStored) ! break; ! } ! return isStored; ! } ! public List<String> getParameters() { ! return this.parameters; ! } ! public List<String> getReturns() { ! return new ArrayList<String>(this.returns); ! } } Index: ExtractCallEdit.java =================================================================== RCS file: /cvsroot/pydev/org.python.pydev.refactoring/src/org/python/pydev/refactoring/coderefactoring/extractmethod/edit/ExtractCallEdit.java,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** ExtractCallEdit.java 20 Oct 2007 19:31:01 -0000 1.4 --- ExtractCallEdit.java 27 Sep 2008 20:00:46 -0000 1.5 *************** *** 25,105 **** public class ExtractCallEdit extends AbstractReplaceEdit { ! private String methodName; ! private int offset; ! private IASTNodeAdapter<?> offsetAdapter; ! private int replaceLength; ! private List<String> callParameters; ! private List<String> returnVariables; ! public ExtractCallEdit(ExtractMethodRequest req) { ! super(req); ! this.methodName = req.getMethodName(); ! this.offset = req.getSelection().getOffset(); ! this.replaceLength = req.getSelection().getLength(); ! this.offsetAdapter = req.getOffsetNode(); ! this.callParameters = req.getParameters(); ! this.returnVariables = req.getReturnVariables(); ! } ! @Override ! protected SimpleNode getEditNode() { ! List<exprType> argsList = initCallArguments(); ! Call methodCall = new Call(createCallAttribute(), argsList.toArray(new exprType[0]), null, null, null); ! return initSubstituteCall(methodCall); ! } ! private SimpleNode initSubstituteCall(Call methodCall) { ! if (returnVariables.size() == 0) { ! return methodCall; ! } else { ! List<exprType> returnExpr = new ArrayList<exprType>(); ! for (String returnVar : returnVariables) { ! returnExpr.add(new Name(returnVar, Name.Store)); ! } ! return new Assign(returnExpr.toArray(new exprType[0]), methodCall); ! } ! } ! private List<exprType> initCallArguments() { ! List<exprType> argsList = new ArrayList<exprType>(); ! for (String parameter : callParameters) { ! argsList.add(new Name(parameter, Name.Load)); ! } ! return argsList; ! } ! private exprType createCallAttribute() { ! if (this.offsetAdapter instanceof IClassDefAdapter) { ! return new Attribute(new Name("self", Name.Load), new NameTok(this.methodName, NameTok.Attrib), Attribute.Load); ! } else { ! return new Name(this.methodName, Name.Load); ! } ! } ! @Override ! public int getOffsetStrategy() { ! return 0; ! } ! @Override ! public int getOffset() { ! return offset; ! } ! @Override ! protected int getReplaceLength() { ! return replaceLength; ! } } --- 25,105 ---- public class ExtractCallEdit extends AbstractReplaceEdit { ! private String methodName; ! private int offset; ! private IASTNodeAdapter<?> offsetAdapter; ! private int replaceLength; ! private List<String> callParameters; ! private List<String> returnVariables; ! public ExtractCallEdit(ExtractMethodRequest req) { ! super(req); ! this.methodName = req.getMethodName(); ! this.offset = req.getSelection().getOffset(); ! this.replaceLength = req.getSelection().getLength(); ! this.offsetAdapter = req.getOffsetNode(); ! this.callParameters = req.getParameters(); ! this.returnVariables = req.getReturnVariables(); ! } ! @Override ! protected SimpleNode getEditNode() { ! List<exprType> argsList = initCallArguments(); ! Call methodCall = new Call(createCallAttribute(), argsList.toArray(new exprType[0]), null, null, null); ! return initSubstituteCall(methodCall); ! } ! private SimpleNode initSubstituteCall(Call methodCall) { ! if (returnVariables.size() == 0) { ! return methodCall; ! } else { ! List<exprType> returnExpr = new ArrayList<exprType>(); ! for (String returnVar : returnVariables) { ! returnExpr.add(new Name(returnVar, Name.Store)); ! } ! return new Assign(returnExpr.toArray(new exprType[0]), methodCall); ! } ! } ! private List<exprType> initCallArguments() { ! List<exprType> argsList = new ArrayList<exprType>(); ! for (String parameter : callParameters) { ! argsList.add(new Name(parameter, Name.Load)); ! } ! return argsList; ! } ! private exprType createCallAttribute() { ! if (this.offsetAdapter instanceof IClassDefAdapter) { ! return new Attribute(new Name("self", Name.Load), new NameTok(this.methodName, NameTok.Attrib), Attribute.Load); ! } else { ! return new Name(this.methodName, Name.Load); ! } ! } ! @Override ! public int getOffsetStrategy() { ! return 0; ! } ! @Override ! public int getOffset() { ! return offset; ! } ! @Override ! protected int getReplaceLength() { ! return replaceLength; ! } } |