| /******************************************************************************* |
| * Copyright (c) 2004, 2015 IBM Corporation and others. |
| * |
| * This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License 2.0 |
| * which accompanies this distribution, and is available at |
| * https://www.eclipse.org/legal/epl-2.0/ |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| * |
| * Contributors: |
| * IBM Corporation - initial implementation |
| *******************************************************************************/ |
| package org.eclipse.jdt.internal.debug.ui.actions; |
| |
| import org.eclipse.debug.core.DebugException; |
| import org.eclipse.debug.core.model.IVariable; |
| import org.eclipse.debug.ui.actions.IVariableValueEditor; |
| import org.eclipse.jdt.internal.debug.eval.ast.engine.ASTInstructionCompiler; |
| import org.eclipse.jdt.internal.debug.ui.IJavaDebugHelpContextIds; |
| import org.eclipse.jdt.internal.debug.ui.JDIDebugUIPlugin; |
| import org.eclipse.jface.dialogs.IInputValidator; |
| import org.eclipse.jface.dialogs.InputDialog; |
| import org.eclipse.jface.window.Window; |
| import org.eclipse.osgi.util.NLS; |
| import org.eclipse.swt.widgets.Composite; |
| import org.eclipse.swt.widgets.Control; |
| import org.eclipse.swt.widgets.Shell; |
| import org.eclipse.ui.IWorkbench; |
| import org.eclipse.ui.PlatformUI; |
| |
| /** |
| * A variable value editor that prompts the user to set a primitive's value. |
| */ |
| public class JavaPrimitiveValueEditor implements IVariableValueEditor { |
| |
| /** |
| * The signature of the edited variable. |
| */ |
| private String fSignature= null; |
| |
| /** |
| * Creates a new editor for a variable with the given signature |
| * @param signature the signature of the primitive to be edited |
| */ |
| public JavaPrimitiveValueEditor(String signature) { |
| fSignature= signature; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.debug.ui.actions.IVariableValueEditor#editVariable(org.eclipse.debug.core.model.IVariable, org.eclipse.swt.widgets.Shell) |
| */ |
| @Override |
| public boolean editVariable(IVariable variable, Shell shell) { |
| try { |
| String name= variable.getName(); |
| String title= ActionMessages.JavaPrimitiveValueEditor_0; |
| String message= NLS.bind(ActionMessages.JavaPrimitiveValueEditor_1, new String[] {name}); |
| String initialValue= variable.getValue().getValueString(); |
| PrimitiveValidator validator= new PrimitiveValidator(); |
| InputDialog dialog= new InputDialog(shell, title, message, initialValue, validator){ |
| @Override |
| protected Control createDialogArea(Composite parent) { |
| IWorkbench workbench = PlatformUI.getWorkbench(); |
| workbench.getHelpSystem().setHelp(parent, IJavaDebugHelpContextIds.DEFAULT_INPUT_DIALOG); |
| return super.createDialogArea(parent); |
| } |
| }; |
| if (dialog.open() == Window.OK) { |
| String stringValue = dialog.getValue(); |
| stringValue = formatValue(stringValue); |
| if (stringValue.length() > 1 && stringValue.charAt(0) == '\\') { |
| // Compute value of octal of hexadecimal escape sequence |
| int i= validator.getEscapeValue(stringValue); |
| if (i != Integer.MAX_VALUE) { |
| stringValue= new String(new char[] { (char) i }); |
| } |
| } |
| variable.setValue(stringValue); |
| } |
| } catch (DebugException e) { |
| JDIDebugUIPlugin.errorDialog(shell, ActionMessages.JavaPrimitiveValueEditor_2, ActionMessages.JavaPrimitiveValueEditor_3, e); // |
| } |
| return true; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.debug.ui.actions.IVariableValueEditor#saveVariable(org.eclipse.debug.core.model.IVariable, java.lang.String, org.eclipse.swt.widgets.Shell) |
| */ |
| @Override |
| public boolean saveVariable(IVariable variable, String expression, Shell shell) { |
| return false; |
| } |
| |
| String formatValue(String value) { |
| try { |
| switch (fSignature.charAt(0)) { |
| case 'I': |
| return Integer.toString(ASTInstructionCompiler.parseIntValue(value)); |
| case 'J': |
| return Long.toString(ASTInstructionCompiler.parseLongValue(value)); |
| case 'S': |
| return Short.toString(ASTInstructionCompiler.parseShortValue(value)); |
| case 'F': |
| case 'D': |
| return ASTInstructionCompiler.removePrefixZerosAndUnderscores(value, false); |
| case 'B': |
| return Byte.toString(ASTInstructionCompiler.parseByteValue(value)); |
| } |
| } |
| catch(NumberFormatException nfe) {} |
| return value; |
| } |
| |
| /** |
| * Input validator for primitive types |
| */ |
| protected class PrimitiveValidator implements IInputValidator { |
| /* (non-Javadoc) |
| * @see org.eclipse.jface.dialogs.IInputValidator#isValid(java.lang.String) |
| */ |
| @Override |
| public String isValid(String newText) { |
| String type= null; |
| switch (fSignature.charAt(0)) { |
| case 'B': |
| try { |
| Byte.parseByte(newText); |
| } catch (NumberFormatException e) { |
| type= "byte"; //$NON-NLS-1$ |
| } |
| break; |
| case 'C': |
| if (newText.length() > 1 && newText.charAt(0) == '\\') { |
| // Possibly an escaped character |
| if (isSpecialCharacter(newText) || |
| isOctalEscape(newText) || |
| isUnicode(newText)) { |
| break; |
| } |
| } |
| if (newText.length() != 1) { |
| type="char"; //$NON-NLS-1$ |
| } |
| break; |
| case 'D': |
| try { |
| Double.parseDouble(ASTInstructionCompiler.removePrefixZerosAndUnderscores(newText, false)); |
| } catch (NumberFormatException e) { |
| type="double"; //$NON-NLS-1$ |
| } |
| break; |
| case 'F': |
| try { |
| Float.parseFloat(ASTInstructionCompiler.removePrefixZerosAndUnderscores(newText, false)); |
| } catch (NumberFormatException e) { |
| type="float"; //$NON-NLS-1$ |
| } |
| break; |
| case 'I': |
| try { |
| ASTInstructionCompiler.parseIntValue(newText); |
| } catch (NumberFormatException e) { |
| type="int"; //$NON-NLS-1$ |
| } |
| break; |
| case 'J': |
| try { |
| ASTInstructionCompiler.parseLongValue(newText); |
| } catch (NumberFormatException e) { |
| type="long"; //$NON-NLS-1$ |
| } |
| break; |
| case 'S': |
| try { |
| ASTInstructionCompiler.parseShortValue(newText); |
| } catch (NumberFormatException e) { |
| type="short"; //$NON-NLS-1$ |
| } |
| break; |
| case 'Z': |
| if (!("true".equals(newText) || "false".equals(newText))) { //$NON-NLS-1$ //$NON-NLS-2$ |
| type="boolean"; //$NON-NLS-1$ |
| } |
| break; |
| } |
| if (type != null) { |
| return NLS.bind(ActionMessages.JavaPrimitiveValueEditor_4, new String[] { type }); |
| } |
| return null; |
| } |
| |
| private boolean isUnicode(String newText) { |
| if (newText.length() == 6) { |
| if (newText.charAt(1) == 'u') { |
| char[] chars = newText.toCharArray(); |
| for (int i = 2; i < chars.length; i++) { |
| if (!isHexDigit(chars[i])) { |
| return false; |
| } |
| } |
| return true; |
| } |
| } |
| return false; |
| } |
| |
| private boolean isOctalEscape(String newText) { |
| char[] chars= newText.toCharArray(); |
| if (chars.length < 4) { |
| for (int i = 1; i < chars.length; i++) { |
| if (!isOctalDigit(chars[i])) { |
| return false; |
| } |
| } |
| return true; |
| } else if (chars.length == 4) { |
| char ch= chars[1]; |
| if (ch < '0' || ch > '3') { |
| return false; |
| } |
| for (int i = 2; i < chars.length; i++) { |
| if (!isOctalDigit(chars[i])) { |
| return false; |
| } |
| } |
| return true; |
| } |
| return false; |
| } |
| |
| private boolean isSpecialCharacter(String newText) { |
| char ch= newText.charAt(1); |
| return newText.length() == 2 && |
| (ch == 'b' || |
| ch == 't' || |
| ch == 'n' || |
| ch == 'f' || |
| ch == 'r' || |
| ch == '"' || |
| ch == '\'' || |
| ch == '\\'); |
| } |
| |
| |
| private boolean isOctalDigit(char ch) { |
| return Character.digit(ch, 8) != -1; |
| } |
| |
| private boolean isHexDigit(char ch) { |
| return Character.digit(ch, 16) != -1; |
| } |
| |
| /** |
| * Returns the integer value specified by the given string, which |
| * represents an octal or hexadecimal escape sequence. Returns |
| * Integer.MAX_VALUE if the given string is not a valid octal or |
| * hexadecimal escape sequence. |
| * |
| * @param string |
| * @return |
| */ |
| protected int getEscapeValue(String string) { |
| return ASTInstructionCompiler.parseIntValue(string); |
| } |
| } |
| |
| } |