Index: model/org/eclipse/jdt/core/IJavaModelMarker.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IJavaModelMarker.java,v --- model/org/eclipse/jdt/core/IJavaModelMarker.java 27 Jun 2008 16:04:01 -0000 1.41 +++ model/org/eclipse/jdt/core/IJavaModelMarker.java 11 Feb 2010 19:20:13 -0000 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2008 IBM Corporation and others. + * Copyright (c) 2000, 2010 IBM Corporation 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 @@ -10,6 +10,8 @@ *******************************************************************************/ package org.eclipse.jdt.core; +import org.eclipse.core.resources.IMarker; + /** * Markers used by the Java model. *

@@ -60,9 +62,11 @@ * Id marker attribute (value "arguments"). Arguments are * concatenated into one String, prefixed with an argument count (followed * with colon separator) and separated with '#' characters. For example: { - * "foo", "bar" } is encoded as "2:foo#bar", { } is encoded as "0: " + * "foo", "bar" } is encoded as "2:foo#bar", { } is encoded as "0:". + *

Empty argument is encoded as three spaces (" ").

* * @since 2.0 + * @see CorrectionEngine#getProblemArguments(IMarker) */ String ARGUMENTS = "arguments"; //$NON-NLS-1$ Index: model/org/eclipse/jdt/internal/core/ClassFileInfo.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClassFileInfo.java,v --- model/org/eclipse/jdt/internal/core/ClassFileInfo.java 13 Aug 2009 01:18:16 -0000 1.46 +++ model/org/eclipse/jdt/internal/core/ClassFileInfo.java 11 Feb 2010 19:20:13 -0000 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2009 IBM Corporation and others. + * Copyright (c) 2000, 2010 IBM Corporation 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 @@ -139,7 +139,7 @@ final Object value; if (values.size() == 0) { if ((tagBits & TagBits.AnnotationTarget) != 0) - value = new String[0]; + value = CharOperation.NO_STRINGS; else return Annotation.NO_MEMBER_VALUE_PAIRS; } else if (values.size() == 1) { Index: model/org/eclipse/jdt/internal/core/util/Util.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Util.java,v --- model/org/eclipse/jdt/internal/core/util/Util.java 12 Nov 2009 16:47:47 -0000 1.139 +++ model/org/eclipse/jdt/internal/core/util/Util.java 11 Feb 2010 19:20:13 -0000 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2009 IBM Corporation and others. + * Copyright (c) 2000, 2010 IBM Corporation 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 @@ -95,7 +95,7 @@ public org.eclipse.jdt.internal.compiler.ast.ASTNode get(Binding binding); } - private static final String ARGUMENTS_DELIMITER = "#"; //$NON-NLS-1$ + private static final char ARGUMENTS_DELIMITER = '#'; private static final String EMPTY_ARGUMENT = " "; //$NON-NLS-1$ @@ -1058,7 +1058,7 @@ if(arguments[j].length() == 0) { args.append(EMPTY_ARGUMENT); } else { - args.append(arguments[j]); + encodeArgument(arguments[j], args); } } @@ -1066,6 +1066,27 @@ } /** + * Encode the argument by doubling the '#' if present into the argument value. + * + *

This stores the encoded argument into the given buffer.

+ * + * @param argument the given argument + * @param buffer the buffer in which the encoded argument is stored + */ + private static void encodeArgument(String argument, StringBuffer buffer) { + for (int i = 0, max = argument.length(); i < max; i++) { + char charAt = argument.charAt(i); + switch(charAt) { + case ARGUMENTS_DELIMITER : + buffer.append(ARGUMENTS_DELIMITER).append(ARGUMENTS_DELIMITER); + break; + default: + buffer.append(charAt); + } + } + } + + /** * Separate all the arguments of a String made by getProblemArgumentsForMarker */ public static String[] getProblemArgumentsFromMarker(String argumentsString){ @@ -1075,7 +1096,7 @@ return null; int length = argumentsString.length(); - int numberOfArg; + int numberOfArg = 0; try{ numberOfArg = Integer.parseInt(argumentsString.substring(0 , index)); } catch (NumberFormatException e) { @@ -1083,22 +1104,64 @@ } argumentsString = argumentsString.substring(index + 1, length); - String[] args = new String[length]; - int count = 0; + return decodeArgumentString(numberOfArg, argumentsString); + } - StringTokenizer tokenizer = new StringTokenizer(argumentsString, ARGUMENTS_DELIMITER); - while(tokenizer.hasMoreTokens()) { - String argument = tokenizer.nextToken(); - if(argument.equals(EMPTY_ARGUMENT)) - argument = ""; //$NON-NLS-1$ - args[count++] = argument; + private static String[] decodeArgumentString(int length, String argumentsString) { + // decode the argumentString knowing that '#' is doubled if part of the argument value + if (length == 0) { + if (argumentsString.length() != 0) { + return null; + } + return CharOperation.NO_STRINGS; } - - if(count != numberOfArg) + String[] result = new String[length]; + int count = 0; + StringBuffer buffer = new StringBuffer(); + for (int i = 0, max = argumentsString.length(); i < max; i++) { + char current = argumentsString.charAt(i); + switch(current) { + case ARGUMENTS_DELIMITER : + /* check the next character. If this is also ARGUMENTS_DELIMITER then only put one into the + * decoded argument and proceed with the next character + */ + if ((i + 1) == max) { + return null; + } + char next = argumentsString.charAt(i + 1); + if (next == ARGUMENTS_DELIMITER) { + buffer.append(ARGUMENTS_DELIMITER); + i++; // proceed with the next character + } else { + // this means the current argument is over + String currentArgumentContents = String.valueOf(buffer); + if (EMPTY_ARGUMENT.equals(currentArgumentContents)) { + currentArgumentContents = org.eclipse.jdt.internal.compiler.util.Util.EMPTY_STRING; + } + result[count++] = currentArgumentContents; + if (count > length) { + // too many elements - ill-formed + return null; + } + buffer.delete(0, buffer.length()); + } + break; + default : + buffer.append(current); + } + } + // process last argument + String currentArgumentContents = String.valueOf(buffer); + if (EMPTY_ARGUMENT.equals(currentArgumentContents)) { + currentArgumentContents = org.eclipse.jdt.internal.compiler.util.Util.EMPTY_STRING; + } + result[count++] = currentArgumentContents; + if (count > length) { + // too many elements - ill-formed return null; - - System.arraycopy(args, 0, args = new String[count], 0, count); - return args; + } + buffer.delete(0, buffer.length()); + return result; } /** @@ -1382,7 +1445,7 @@ } } else { - parameterSignatures = new String[0]; + parameterSignatures = CharOperation.NO_STRINGS; } return (JavaElement) declaringType.getMethod(String.valueOf(methodDeclaration.selector), parameterSignatures); } Index: src/org/eclipse/jdt/core/tests/model/AllJavaModelTests.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AllJavaModelTests.java,v --- src/org/eclipse/jdt/core/tests/model/AllJavaModelTests.java 27 Jun 2008 16:02:38 -0000 1.75 +++ src/org/eclipse/jdt/core/tests/model/AllJavaModelTests.java 11 Feb 2010 19:20:14 -0000 @@ -180,6 +180,9 @@ // Creation of imports CreateImportsTests.class, + + // Util tests + UtilTests.class, }; Class[] deprecatedClasses = getDeprecatedJDOMTestClasses(); Index: src/org/eclipse/jdt/core/tests/model/UtilTests.java =================================================================== RCS file: src/org/eclipse/jdt/core/tests/model/UtilTests.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/org/eclipse/jdt/core/tests/model/UtilTests.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,51 @@ +/******************************************************************************* + * Copyright (c) 2010 IBM Corporation 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: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.jdt.core.tests.model; + +import org.eclipse.jdt.internal.core.util.Util; + +import junit.framework.Test; + +public class UtilTests extends AbstractJavaModelTests { + + static { +// TESTS_PREFIX = "testInvalidCompilerOptions"; +// TESTS_NAMES = new String[] { "test028"}; + } + + public UtilTests(String name) { + super(name); + } + + public static Test suite() { + return buildModelTestSuite(UtilTests.class); + } + public void test001() { + String[] arguments = Util.getProblemArgumentsFromMarker("1:foo"); + assertStringsEqual("Wrong arguments", new String[] {"foo"}, arguments); + } + public void test002() { + String[] arguments = Util.getProblemArgumentsFromMarker("2:foo#bar"); + assertStringsEqual("Wrong arguments", new String[] {"foo", "bar"}, arguments); + } + public void test003() { + String[] arguments = Util.getProblemArgumentsFromMarker("1: "); + assertStringsEqual("Wrong arguments", new String[] {""}, arguments); + } + public void test004() { + String[] arguments = Util.getProblemArgumentsFromMarker("0:"); + assertStringsEqual("Wrong arguments", new String[0], arguments); + } + public void test005() { + String[] arguments = Util.getProblemArgumentsFromMarker("3:Task#getTaskListeners# "); + assertStringsEqual("Wrong arguments", new String[] {"Task", "getTaskListeners", ""}, arguments); + } +}