From 86d0c343f953c0ca0620f258e53394328f515b64 Mon Sep 17 00:00:00 2001 From: Sergey Prigogin Date: Mon, 31 May 2010 02:37:27 +0000 Subject: [PATCH] Infinite loop in Implement Method command. Bug 312172. --- .../ui/refactoring/utils/NameHelper.java | 93 ++++++++++--------- .../utils/PseudoNameGenerator.java | 17 ++-- 2 files changed, 59 insertions(+), 51 deletions(-) diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/utils/NameHelper.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/utils/NameHelper.java index 96232697b23..777b3736354 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/utils/NameHelper.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/utils/NameHelper.java @@ -16,13 +16,17 @@ import java.util.regex.Pattern; import org.eclipse.core.resources.IFile; import org.eclipse.core.runtime.CoreException; -import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier; +import org.eclipse.cdt.core.dom.ast.ASTTypeUtil; +import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration; -import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamedTypeSpecifier; +import org.eclipse.cdt.core.dom.ast.IBinding; +import org.eclipse.cdt.core.dom.ast.IType; +import org.eclipse.cdt.core.dom.ast.IVariable; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName; import org.eclipse.cdt.core.parser.Keywords; import org.eclipse.cdt.core.parser.util.CharArrayIntMap; +import org.eclipse.cdt.ui.CUIPlugin; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTQualifiedName; @@ -33,8 +37,6 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTQualifiedName; * */ public class NameHelper { - - private static final String localVariableRegexp = "[a-z_A-Z]\\w*"; //$NON-NLS-1$ public static boolean isValidLocalVariableName(String name) { @@ -63,14 +65,14 @@ public class NameHelper { * @throws CoreException */ public static ICPPASTQualifiedName createQualifiedNameFor(IASTName declaratorName, IFile declarationFile, int selectionOffset, IFile insertFile, int insertLocation) - throws CoreException { + throws CoreException { ICPPASTQualifiedName qname = new CPPASTQualifiedName(); IASTName[] declarationNames = NamespaceHelper.getSurroundingNamespace(declarationFile, selectionOffset).getNames(); IASTName[] implementationNames = NamespaceHelper.getSurroundingNamespace(insertFile, insertLocation).getNames(); - for(int i = 0; i < declarationNames.length; i++) { - if(i >= implementationNames.length) { + for (int i = 0; i < declarationNames.length; i++) { + if (i >= implementationNames.length) { qname.addName(declarationNames[i]); } else if (!String.valueOf(declarationNames[i].toCharArray()).equals(String.valueOf(implementationNames[i].toCharArray()))) { qname.addName(declarationNames[i]); @@ -93,54 +95,59 @@ public class NameHelper { char[] letters = fieldName.toCharArray(); int start = 0; int end = letters.length - 1; - try{ - - // Trim, non-letters at the beginning - while(!Character.isLetterOrDigit(letters[start]) && start < end) { - ++start; - } - - // If the next character is not a letter or digit, - // look ahead because the first letter might not be needed - if (start + 1 <= end - && !Character.isLetterOrDigit(letters[start + 1])) { - int lookAhead = 1; - while (start + lookAhead <= end) { - // Only change the start if something is found after the non-letters - if (Character.isLetterOrDigit(letters[start + lookAhead])) { - start += lookAhead; - break; - } - lookAhead++; + try { + // Trim, non-letters at the beginning + while (!Character.isLetterOrDigit(letters[start]) && start < end) { + ++start; } - } else if (start + 1 <= end - && Character.isUpperCase(letters[start + 1])) { - start++; - } - - // Trim, non-letters at the end - while((!Character.isLetter(letters[end]) && !Character.isDigit(letters[end])) && start < end) { - --end; - } - }catch(IndexOutOfBoundsException e){} + + // If the next character is not a letter or digit, + // look ahead because the first letter might not be needed + if (start + 1 <= end + && !Character.isLetterOrDigit(letters[start + 1])) { + int lookAhead = 1; + while (start + lookAhead <= end) { + // Only change the start if something is found after the non-letters + if (Character.isLetterOrDigit(letters[start + lookAhead])) { + start += lookAhead; + break; + } + lookAhead++; + } + } else if (start + 1 <= end && Character.isUpperCase(letters[start + 1])) { + start++; + } + + // Trim, non-letters at the end + while ((!Character.isLetter(letters[end]) && !Character.isDigit(letters[end])) && start < end) { + --end; + } + } catch (IndexOutOfBoundsException e) { + } return new String(letters, start, end - start + 1); - } public static String makeFirstCharUpper(String name) { - if(Character.isLowerCase(name.charAt(0))){ + if (Character.isLowerCase(name.charAt(0))){ name = Character.toUpperCase(name.charAt(0)) + name.substring(1); } return name; } public static String getTypeName(IASTParameterDeclaration parameter) { - IASTDeclSpecifier parameterDeclSpecifier = parameter.getDeclSpecifier(); - if (parameterDeclSpecifier instanceof ICPPASTNamedTypeSpecifier) { - return ((ICPPASTNamedTypeSpecifier) parameterDeclSpecifier).getName().getRawSignature(); - } else { - return parameterDeclSpecifier.getRawSignature(); + IASTName name = parameter.getDeclarator().getName(); + IBinding binding = name.resolveBinding(); + if (binding instanceof IVariable) { + try { + IType type = ((IVariable) binding).getType(); + if (type != null) { + return ASTTypeUtil.getType(type); + } + } catch (DOMException e) { + CUIPlugin.log(e); + } } + return ""; //$NON-NLS-1$ } } diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/utils/PseudoNameGenerator.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/utils/PseudoNameGenerator.java index bea2edf203b..3e6be1e4698 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/utils/PseudoNameGenerator.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/utils/PseudoNameGenerator.java @@ -29,23 +29,22 @@ public class PseudoNameGenerator { } public String generateNewName(String typeName) { - String[] nameParts = typeName.split("::"); //$NON-NLS-1$ typeName = nameParts[nameParts.length - 1]; - if(typeName.contains("<")) { //$NON-NLS-1$ + if (typeName.contains("<")) { //$NON-NLS-1$ typeName = typeName.substring(0, typeName.indexOf('<')); } - if(typeName.length() != 0) { + if (typeName.length() != 0) { typeName = typeName.substring(0, 1).toLowerCase() + typeName.substring(1); } nameParts = typeName.split("\\s"); //$NON-NLS-1$ for (int i = 0; i < nameParts.length; i++) { - if(i <= 0) { + if (i <= 0) { typeName = nameParts[i]; - }else { + } else { typeName = typeName.concat(nameParts[i].substring(0,1).toUpperCase()); - if(nameParts[i].length() > 1) { + if (nameParts[i].length() > 1) { typeName = typeName.concat(nameParts[i].substring(1)); } } @@ -57,12 +56,14 @@ public class PseudoNameGenerator { do { newNameCandidate = typeName + numberString; + if (!NameHelper.isValidLocalVariableName(newNameCandidate)) { + return ""; //$NON-NLS-1$ + } index++; numberString = Integer.toString(index); - } while(names.contains(newNameCandidate) || !NameHelper.isValidLocalVariableName(newNameCandidate) || NameHelper.isKeyword(newNameCandidate)); + } while (names.contains(newNameCandidate) || NameHelper.isKeyword(newNameCandidate)); names.add(newNameCandidate); - return newNameCandidate; } }