From 5c49628e1936743d46eb9513e71af1e83ac8c6f4 Mon Sep 17 00:00:00 2001 From: aclement Date: Mon, 12 May 2008 18:00:21 +0000 Subject: [PATCH] 231396: refactoring: Moved CharOperation and NameConvertor --- .../aspectj/asm/internal/CharOperation.java | 116 ++++++++++ .../asm/internal/JDTLikeHandleProvider.java | 2 - .../aspectj/asm/internal/NameConvertor.java | 214 ++++++++++++++++++ .../aspectj/asm/internal/ProgramElement.java | 2 - .../org/aspectj/asm/AsmModuleTests.java | 3 + .../org/aspectj/asm/NameConvertorTest.java | 86 +++++++ 6 files changed, 419 insertions(+), 4 deletions(-) create mode 100644 asm/src/org/aspectj/asm/internal/CharOperation.java create mode 100644 asm/src/org/aspectj/asm/internal/NameConvertor.java create mode 100644 asm/testsrc/org/aspectj/asm/NameConvertorTest.java diff --git a/asm/src/org/aspectj/asm/internal/CharOperation.java b/asm/src/org/aspectj/asm/internal/CharOperation.java new file mode 100644 index 000000000..6432c3a88 --- /dev/null +++ b/asm/src/org/aspectj/asm/internal/CharOperation.java @@ -0,0 +1,116 @@ +/******************************************************************** + * Copyright (c) 2006 Contributors. 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://eclipse.org/legal/epl-v10.html + * + * Contributors: IBM Corporation - initial API and implementation + * Helen Hawkins - initial version + *******************************************************************/ +package org.aspectj.asm.internal; + + +/** + * Taken from org.aspectj.org.eclipse.jdt.core.compiler.CharOperation + * + */ +public class CharOperation { + + /** + * Taken from org.aspectj.org.eclipse.jdt.core.compiler.CharOperation + */ + public static final char[] subarray(char[] array, int start, int end) { + if (end == -1) + end = array.length; + if (start > end) + return null; + if (start < 0) + return null; + if (end > array.length) + return null; + + char[] result = new char[end - start]; + System.arraycopy(array, start, result, 0, end - start); + return result; + } + + /** + * Taken from org.aspectj.org.eclipse.jdt.core.compiler.CharOperation + */ + public static final int lastIndexOf(char toBeFound, char[] array) { + for (int i = array.length; --i >= 0;) + if (toBeFound == array[i]) + return i; + return -1; + } + +// /** +// * Taken from org.aspectj.org.eclipse.jdt.core.compiler.CharOperation +// */ +// public static final boolean contains(char character, char[] array) { +// for (int i = array.length; --i >= 0;) +// if (array[i] == character) +// return true; +// return false; +// } + + /** + * Taken from org.aspectj.org.eclipse.jdt.core.compiler.CharOperation + */ + public static final int indexOf(char toBeFound, char[] array) { + for (int i = 0; i < array.length; i++) + if (toBeFound == array[i]) + return i; + return -1; + } + + /** + * Taken from org.aspectj.org.eclipse.jdt.core.compiler.CharOperation + */ + public static final char[] concat(char[] first, char[] second) { + if (first == null) + return second; + if (second == null) + return first; + + int length1 = first.length; + int length2 = second.length; + char[] result = new char[length1 + length2]; + System.arraycopy(first, 0, result, 0, length1); + System.arraycopy(second, 0, result, length1, length2); + return result; + } + + /** + * Taken from org.aspectj.org.eclipse.jdt.core.compiler.CharOperation + */ + public static final boolean equals(char[] first, char[] second) { + if (first == second) + return true; + if (first == null || second == null) + return false; + if (first.length != second.length) + return false; + + for (int i = first.length; --i >= 0;) + if (first[i] != second[i]) + return false; + return true; + } + + /** + * Taken from org.aspectj.org.eclipse.jdt.core.compiler.CharOperation + */ + public static final void replace( + char[] array, + char toBeReplaced, + char replacementChar) { + if (toBeReplaced != replacementChar) { + for (int i = 0, max = array.length; i < max; i++) { + if (array[i] == toBeReplaced) + array[i] = replacementChar; + } + } + } +} diff --git a/asm/src/org/aspectj/asm/internal/JDTLikeHandleProvider.java b/asm/src/org/aspectj/asm/internal/JDTLikeHandleProvider.java index 712356e59..985c841c6 100644 --- a/asm/src/org/aspectj/asm/internal/JDTLikeHandleProvider.java +++ b/asm/src/org/aspectj/asm/internal/JDTLikeHandleProvider.java @@ -18,8 +18,6 @@ import org.aspectj.asm.AsmManager; import org.aspectj.asm.IElementHandleProvider; import org.aspectj.asm.IProgramElement; import org.aspectj.bridge.ISourceLocation; -import org.aspectj.util.CharOperation; -import org.aspectj.util.NameConvertor; /** * Creates JDT-like handles, for example diff --git a/asm/src/org/aspectj/asm/internal/NameConvertor.java b/asm/src/org/aspectj/asm/internal/NameConvertor.java new file mode 100644 index 000000000..bd4609979 --- /dev/null +++ b/asm/src/org/aspectj/asm/internal/NameConvertor.java @@ -0,0 +1,214 @@ +/******************************************************************** + * Copyright (c) 2006 Contributors. 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://eclipse.org/legal/epl-v10.html + * + * Contributors: IBM Corporation - initial API and implementation + * Helen Hawkins - initial version + *******************************************************************/ +package org.aspectj.asm.internal; + + +public class NameConvertor { + + private static final char BOOLEAN = 'Z'; + private static final char BYTE = 'B'; + private static final char CHAR = 'C'; + private static final char DOUBLE = 'D'; + private static final char FLOAT = 'F'; + private static final char INT = 'I'; + private static final char LONG = 'J'; + private static final char SHORT = 'S'; + private static final char ARRAY = '['; + private static final char RESOLVED = 'L'; + private static final char UNRESOLVED = 'Q'; + + public static final char PARAMETERIZED = 'P'; + + private static final char[] BOOLEAN_NAME = new char[]{'b','o','o','l','e','a','n'}; + private static final char[] BYTE_NAME = new char[]{'b','y','t','e'}; + private static final char[] CHAR_NAME = new char[]{'c','h','a','r'}; + private static final char[] DOUBLE_NAME = new char[]{'d','o','u','b','l','e'}; + private static final char[] FLOAT_NAME = new char[]{'f','l','o','a','t'}; + private static final char[] INT_NAME = new char[]{'i','n','t'}; + private static final char[] LONG_NAME = new char[]{'l','o','n','g'}; + private static final char[] SHORT_NAME = new char[]{'s','h','o','r','t'}; + + private static final char[] SQUARE_BRACKETS = new char[]{'[',']'}; + private static final char[] GREATER_THAN = new char[]{'>'}; + private static final char[] LESS_THAN = new char[]{'<'}; + private static final char[] COMMA = new char[]{','}; + private static final char[] BACKSLASH_LESSTHAN = new char[]{'\\','<'}; + private static final char[] SEMICOLON = new char[]{';'}; + + + /** + * Creates a readable name from the given char array, for example, + * given 'I' returns 'int'. Moreover, given + * 'Ljava/lang/String;' returns + * 'java.lang.String' + */ + public static char[] convertFromSignature(char[] c) { + int lt = CharOperation.indexOf('<',c); + int sc = CharOperation.indexOf(';',c); + int gt = CharOperation.indexOf('>',c); + + int smallest = 0; + if (lt == -1 && sc == -1 && gt == -1) { + // we have something like 'Ljava/lang/String' or 'I' + return getFullyQualifiedTypeName(c); + } else if (lt != -1 && (sc == -1 || lt <= sc) && (gt == -1 || lt <= gt)) { + // we have something like 'Ljava/lang/String;' + smallest = gt; + } + char[] first = CharOperation.subarray(c,0,smallest); + char[] second = CharOperation.subarray(c,smallest+1,c.length); + if (smallest == 0 && first.length == 0 && c[0] == '>') { + // c = {'>',';'} therefore we just want to return '>' to + // close the generic signature + return GREATER_THAN; + } else if (first.length == 1 && second.length == 0) { + return first; + } else if (second.length == 0 || (second.length == 1 && second[0] == ';')){ + // we've reached the end of the array, therefore only care about + // the first part + return convertFromSignature(first); + } else if (smallest == lt) { + // if c = 'Ljava/lang/String;' + char[] inclComma = CharOperation.concat(convertFromSignature(first),COMMA); + return CharOperation.concat(inclComma,convertFromSignature(second)); + } + return CharOperation.concat(convertFromSignature(first),convertFromSignature(second)); + } + + + /** + * Given a char array, returns the type name for this. For example + * 'I' returns 'int', 'Ljava/lang/String' returns 'java.lang.String' and + * '[Ljava/lang/String' returns 'java.lang.String[]' + * + * NOTE: Doesn't go any deaper so given 'Ljava/lang/String;' + * it would return 'java.lang.String;', however, only called + * with something like 'Ljava/lang/String' + */ + private static char[] getFullyQualifiedTypeName(char[] c) { + if (c.length == 0) { + return c; + } + if (c[0] == BOOLEAN) { + return BOOLEAN_NAME; + } else if (c[0] == BYTE) { + return BYTE_NAME; + } else if (c[0] == CHAR) { + return CHAR_NAME; + } else if (c[0] == DOUBLE) { + return DOUBLE_NAME; + } else if (c[0] == FLOAT) { + return FLOAT_NAME; + } else if (c[0] == INT) { + return INT_NAME; + } else if (c[0] == LONG) { + return LONG_NAME; + } else if (c[0] == SHORT) { + return SHORT_NAME; + } else if (c[0] == ARRAY) { + return CharOperation.concat( + getFullyQualifiedTypeName(CharOperation.subarray(c,1,c.length)), + SQUARE_BRACKETS); + } else { + char[] type = CharOperation.subarray(c,1,c.length); + CharOperation.replace(type,'/','.'); + return type; + } + } + + /** + * Given 'Ppkg/MyGenericClass;' + * will return 'QMyGenericClass;' + */ + public static char[] createShortName(char[] c) { + int lt = CharOperation.indexOf('<',c); + int sc = CharOperation.indexOf(';',c); + int gt = CharOperation.indexOf('>',c); + + int smallest = 0; + if (lt == -1 && sc == -1 && gt == -1) { + // we have something like 'Ljava/lang/String' or 'I' + return getTypeName(c); + } else if (lt != -1 && (sc == -1 || lt <= sc) && (gt == -1 || lt <= gt)) { + // we have something like 'Ljava/lang/String;' + smallest = gt; + } + char[] first = CharOperation.subarray(c,0,smallest); + char[] second = CharOperation.subarray(c,smallest+1,c.length); + if (smallest == 0 && first.length == 0 && c[0] == '>') { + // c = {'>',';'} therefore we just want to return c to + // close the generic signature + return c; + } else if (first.length == 1 && second.length == 0) { + return first; + } else if (second.length == 0 || (second.length == 1 && second[0] == ';')){ + // we've reached the end of the array, therefore only care about + // the first part + return createShortName(first); + } else if (smallest == lt) { + // if c = 'Ljava/lang/String;;", + "java.util.List"); + } + public void testClassParameterizedWithStringAndType() { + checkConversion("PMyGenericClass;", + "MyGenericClass"); + } + public void testStringArray() { + checkConversion("[Ljava/lang/String;","java.lang.String[]"); + } + public void testTwoDimensionalStringArray() { + checkConversion("[[Ljava/lang/String;","java.lang.String[][]"); + } + public void testIntArray() { + checkConversion("[I","int[]"); + } + + private void checkConversion(String signature, String expected) { + char[] c = NameConvertor.convertFromSignature(signature.toCharArray()); + assertTrue("converting " + signature + ", expected " + expected + "," + + "but found " + String.valueOf(c), + CharOperation.equals(c,expected.toCharArray())); + } + + +} -- 2.39.5