/* * Copyright (c) 2011, the Dart project authors. * * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except * in compliance with the License. You may obtain a copy of the License at * * http://www.eclipse.org/legal/epl-v10.html * * Unless required by applicable law or agreed to in writing, software distributed under the License * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express * or implied. See the License for the specific language governing permissions and limitations under * the License. */ package com.google.dart.tools.ui; import com.google.dart.tools.ui.internal.util.Strings; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IStorage; import org.eclipse.core.runtime.IAdaptable; import org.eclipse.jface.viewers.StyledString; import org.eclipse.osgi.util.TextProcessor; import org.eclipse.ui.IWorkingSet; import org.eclipse.ui.model.IWorkbenchAdapter; /** * <code>DartElementLabels</code> provides helper methods to render names of JavaScript elements. * Provisional API: This class/interface is part of an interim API that is still under development * and expected to change significantly before reaching stability. It is being made available at * this early stage to solicit feedback from pioneering adopters on the understanding that any code * that uses this API will almost certainly be broken (repeatedly) as the API evolves. */ public class DartElementLabels { /** * Method names contain parameter types. e.g. <code>foo(int)</code> */ public final static long M_PARAMETER_TYPES = 1L << 0; /** * Method names contain parameter names. e.g. <code>foo(index)</code> */ public final static long M_PARAMETER_NAMES = 1L << 1; /** * Method names contain type parameters prepended. e.g. <code><A> foo(A index)</code> */ public final static long M_PRE_TYPE_PARAMETERS = 1L << 2; /** * Method names contain type parameters appended. e.g. <code>foo(A index) <A></code> */ public final static long M_APP_TYPE_PARAMETERS = 1L << 3; /** * Method names contain thrown exceptions. e.g. <code>foo throws IOException</code> */ public final static long M_EXCEPTIONS = 1L << 4; /** * Method names contain return type (appended) e.g. <code>foo : int</code> */ public final static long M_APP_RETURNTYPE = 1L << 5; /** * Method names contain return type (appended) e.g. <code>int foo</code> */ public final static long M_PRE_RETURNTYPE = 1L << 6; /** * Method names are fully qualified. e.g. <code>java.util.Vector.size</code> */ public final static long M_FULLY_QUALIFIED = 1L << 7; /** * Method names are post qualified. e.g. <code>size - java.util.Vector</code> */ public final static long M_POST_QUALIFIED = 1L << 8; /** * Initializer names are fully qualified. e.g. <code>java.util.Vector.{ ... }</code> */ public final static long I_FULLY_QUALIFIED = 1L << 10; /** * Type names are post qualified. e.g. <code>{ ... } - java.util.Map</code> */ public final static long I_POST_QUALIFIED = 1L << 11; /** * Field names contain the declared type (appended) e.g. <code>fHello : int</code> */ public final static long F_APP_TYPE_SIGNATURE = 1L << 14; /** * Field names contain the declared type (prepended) e.g. <code>int fHello</code> */ public final static long F_PRE_TYPE_SIGNATURE = 1L << 15; /** * Fields names are fully qualified. e.g. <code>java.lang.System.out</code> */ public final static long F_FULLY_QUALIFIED = 1L << 16; /** * Fields names are post qualified. e.g. <code>out - java.lang.System</code> */ public final static long F_POST_QUALIFIED = 1L << 17; /** * Type names are fully qualified. e.g. <code>java.util.Map.MapEntry</code> */ public final static long T_FULLY_QUALIFIED = 1L << 18; /** * Type names are type container qualified. e.g. <code>Map.MapEntry</code> */ public final static long T_CONTAINER_QUALIFIED = 1L << 19; /** * Type names are post qualified. e.g. <code>MapEntry - java.util.Map</code> */ public final static long T_POST_QUALIFIED = 1L << 20; /** * Type names contain type parameters. e.g. <code>Map<S, T></code> */ public final static long T_TYPE_PARAMETERS = 1L << 21; /** * Declarations (import container / declaration, package declaration) are qualified. e.g. * <code>java.util.Vector.class/import container</code> */ public final static long D_QUALIFIED = 1L << 24; /** * Declarations (import container / declaration, package declaration) are post qualified. e.g. * <code>import container - java.util.Vector.class</code> */ public final static long D_POST_QUALIFIED = 1L << 25; /** * Class file names are fully qualified. e.g. <code>java.util.Vector.class</code> */ public final static long CF_QUALIFIED = 1L << 27; /** * Class file names are post qualified. e.g. <code>Vector.class - java.util</code> */ public final static long CF_POST_QUALIFIED = 1L << 28; /** * Compilation unit names are fully qualified. e.g. <code>java.util.Vector.java</code> */ public final static long CU_QUALIFIED = 1L << 31; /** * Compilation unit names are post qualified. e.g. <code>Vector.JavaScript - java.util</code> */ public final static long CU_POST_QUALIFIED = 1L << 32; /** * Package names are qualified. e.g. <code>MyProject/src/java.util</code> */ public final static long P_QUALIFIED = 1L << 35; /** * Package names are post qualified. e.g. <code>java.util - MyProject/src</code> */ public final static long P_POST_QUALIFIED = 1L << 36; /** * Package names are compressed. e.g. <code>o*.e*.search</code> */ public final static long P_COMPRESSED = 1L << 37; /** * Package Fragment Roots contain variable name if from a variable. e.g. * <code>JRE_LIB - c:\java\lib\rt.jar</code> */ public final static long ROOT_VARIABLE = 1L << 40; /** * Package Fragment Roots contain the project name if not an archive (prepended). e.g. * <code>MyProject/src</code> */ public final static long ROOT_QUALIFIED = 1L << 41; /** * Package Fragment Roots contain the project name if not an archive (appended). e.g. * <code>src - MyProject</code> */ public final static long ROOT_POST_QUALIFIED = 1L << 42; /** * Add root path to all elements except Package Fragment Roots and JavaScript projects. e.g. * <code>java.lang.Vector - c:\java\lib\rt.jar</code> Option only applies to getElementLabel */ public final static long APPEND_ROOT_PATH = 1L << 43; /** * Add root path to all elements except Package Fragment Roots and JavaScript projects. e.g. * <code>java.lang.Vector - c:\java\lib\rt.jar</code> Option only applies to getElementLabel */ public final static long PREPEND_ROOT_PATH = 1L << 44; /** * Post qualify referenced package fragment roots. For example * <code>jdt.jar - com.google.dart.tools.ui</code> if the jar is referenced from another project. */ public final static long REFERENCED_ROOT_POST_QUALIFIED = 1L << 45; /** * Specified to use the resolved information of a Type, IFunction or IField. See * {@link Type#isResolved()}. If resolved information is available, types will be rendered with * type parameters of the instantiated type. Resolved method render with the parameter types of * the method instance. <code>Vector<String>.get(String)</code> */ public final static long USE_RESOLVED = 1L << 48; /** * Prepend first category (if any) to field. */ public final static long F_CATEGORY = 1L << 49; /** * Prepend first category (if any) to method. */ public final static long M_CATEGORY = 1L << 50; /** * Prepend first category (if any) to type. */ public final static long T_CATEGORY = 1L << 51; /** * @deprecated no longer used */ @Deprecated public final static long SHOW_TYPE = 1L << 52; /** * Show category for all elements. */ public final static long ALL_CATEGORY = new Long(DartElementLabels.F_CATEGORY | DartElementLabels.M_CATEGORY | DartElementLabels.T_CATEGORY).longValue(); /** * Qualify all elements */ public final static long ALL_FULLY_QUALIFIED = new Long(F_FULLY_QUALIFIED | M_FULLY_QUALIFIED | I_FULLY_QUALIFIED | T_FULLY_QUALIFIED | D_QUALIFIED | CF_QUALIFIED | CU_QUALIFIED | P_QUALIFIED | ROOT_QUALIFIED).longValue(); /** * Post qualify all elements */ public final static long ALL_POST_QUALIFIED = new Long(F_POST_QUALIFIED | M_POST_QUALIFIED | I_POST_QUALIFIED | T_POST_QUALIFIED | D_POST_QUALIFIED | CF_POST_QUALIFIED | CU_POST_QUALIFIED | P_POST_QUALIFIED | ROOT_POST_QUALIFIED).longValue(); /** * Default options (M_PARAMETER_TYPES, M_APP_TYPE_PARAMETERS & T_TYPE_PARAMETERS enabled) */ public final static long ALL_DEFAULT = new Long(M_PARAMETER_TYPES | M_APP_TYPE_PARAMETERS | T_TYPE_PARAMETERS).longValue(); /** * Default qualify options (All except Root and Package) */ public final static long DEFAULT_QUALIFIED = new Long(F_FULLY_QUALIFIED | M_FULLY_QUALIFIED | I_FULLY_QUALIFIED | T_FULLY_QUALIFIED | D_QUALIFIED | CF_QUALIFIED | CU_QUALIFIED).longValue(); /** * Default post qualify options (All except Root and Package) */ public final static long DEFAULT_POST_QUALIFIED = new Long(F_POST_QUALIFIED | M_POST_QUALIFIED | I_POST_QUALIFIED | T_POST_QUALIFIED | D_POST_QUALIFIED | CF_POST_QUALIFIED | CU_POST_QUALIFIED).longValue(); /** * Specifies to apply color styles to labels. This flag only applies to methods taking or * returning a {@link StyledString}. */ public final static long COLORIZE = 1L << 55; /** * User-readable string for separating post qualified names (e.g. " - "). */ public final static String CONCAT_STRING = DartUIMessages.JavaElementLabels_concat_string; /** * User-readable string for separating list items (e.g. ", "). */ public final static String COMMA_STRING = DartUIMessages.JavaElementLabels_comma_string; /** * User-readable string for separating the return type (e.g. " : "). */ public final static String DECL_STRING = DartUIMessages.JavaElementLabels_declseparator_string; /** * User-readable string for concatenating categories (e.g. " "). XXX: to be made API post 3.2 */ @SuppressWarnings("unused") private final static String CATEGORY_SEPARATOR_STRING = DartUIMessages.JavaElementLabels_category_separator_string; /** * User-readable string for ellipsis ("..."). */ public final static String ELLIPSIS_STRING = "..."; //$NON-NLS-1$ /** * User-readable string for the default package name (e.g. "(default package)"). */ public final static String DEFAULT_PACKAGE = DartUIMessages.JavaElementLabels_default_package; /** * Appends the label for a local variable to a {@link StringBuffer}. * * @param localVariable The element to render. * @param flags The rendering flags. Flags with names starting with 'F_' are considered. * @param buf The buffer to append the resulting label to. TODO implement labels for local * variables */ // public static void getLocalVariableLabel(ILocalVariable localVariable, // long flags, StringBuffer buf) { // if (getFlag(flags, F_PRE_TYPE_SIGNATURE)) { // getTypeSignatureLabel(localVariable.getTypeSignature(), flags, buf); // buf.append(' '); // } // // if (getFlag(flags, F_FULLY_QUALIFIED)) { // getElementLabel(localVariable.getParent(), M_PARAMETER_TYPES // | M_FULLY_QUALIFIED | T_FULLY_QUALIFIED | (flags & QUALIFIER_FLAGS), // buf); // buf.append('.'); // } // // buf.append(localVariable.getDisplayName()); // // if (getFlag(flags, F_APP_TYPE_SIGNATURE)) { // buf.append(DECL_STRING); // getTypeSignatureLabel(localVariable.getTypeSignature(), flags, buf); // } // // // post qualification // if (getFlag(flags, F_POST_QUALIFIED)) { // buf.append(CONCAT_STRING); // getElementLabel(localVariable.getParent(), M_PARAMETER_TYPES // | M_FULLY_QUALIFIED | T_FULLY_QUALIFIED | (flags & QUALIFIER_FLAGS), // buf); // } // } /** * Appends the label for a package fragment to a {@link StringBuffer}. Considers the P_* flags. * * @param pack The element to render. * @param flags The rendering flags. Flags with names starting with P_' are considered. * @param buf The buffer to append the resulting label to. */ // public static void getPackageFragmentLabel(IPackageFragment pack, long flags, // StringBuffer buf) { // if (getFlag(flags, P_QUALIFIED)) { // getPackageFragmentRootLabel((IPackageFragmentRoot) pack.getParent(), // ROOT_QUALIFIED, buf); // buf.append('/'); // } // refreshPackageNamePattern(); // if (pack.isDefaultPackage()) { // buf.append(DEFAULT_PACKAGE); // } else if (getFlag(flags, P_COMPRESSED) && fgPkgNameLength >= 0) { // String name = pack.getDisplayName(); // int start = 0; // int dot = name.indexOf('.', start); // while (dot > 0) { // if (dot - start > fgPkgNameLength - 1) { // buf.append(fgPkgNamePrefix); // if (fgPkgNameChars > 0) // buf.append(name.substring(start, // Math.min(start + fgPkgNameChars, dot))); // buf.append(fgPkgNamePostfix); // } else // buf.append(name.substring(start, dot + 1)); // start = dot + 1; // dot = name.indexOf('.', start); // } // buf.append(name.substring(start)); // } else { // // buf.append(pack.getDisplayName()); // } // if (getFlag(flags, P_POST_QUALIFIED)) { // buf.append(CONCAT_STRING); // getPackageFragmentRootLabel((IPackageFragmentRoot) pack.getParent(), // ROOT_QUALIFIED, buf); // } // } /** * Appends the label for a package fragment root to a {@link StringBuffer}. Considers the ROOT_* * flags. * * @param root The element to render. * @param flags The rendering flags. Flags with names starting with ROOT_' are considered. * @param buf The buffer to append the resulting label to. */ // public static void getPackageFragmentRootLabel(IPackageFragmentRoot root, // long flags, StringBuffer buf) { // if (root.isArchive()) // getArchiveLabel(root, flags, buf); // else // getFolderLabel(root, flags, buf); // } /** * Returns the styled label of the given object. The object must be of type {@link DartElement} or * adapt to {@link IWorkbenchAdapter}. If the element type is not known, the empty string is * returned. The returned label is BiDi-processed with * {@link TextProcessor#process(String, String)}. * * @param obj object to get the label for * @param flags the rendering flags * @return the label or the empty string if the object type is not supported */ public static StyledString getStyledTextLabel(Object obj, long flags) { if (obj instanceof IResource) { return getStyledResourceLabel((IResource) obj); // } else if (obj instanceof ClassPathContainer) { // ClassPathContainer container= (ClassPathContainer) obj; // return getStyledContainerEntryLabel(container.getClasspathEntry().getPath(), container.getJavaProject()); } else if (obj instanceof IStorage) { return getStyledStorageLabel((IStorage) obj); } else if (obj instanceof IAdaptable) { IWorkbenchAdapter wbadapter = (IWorkbenchAdapter) ((IAdaptable) obj).getAdapter(IWorkbenchAdapter.class); if (wbadapter != null) { return Strings.markLTR(new StyledString(wbadapter.getLabel(obj))); } } return new StyledString(); } /** * Returns the label of the given object. The object must be of type {@link DartElement} or adapt * to {@link IWorkbenchAdapter}. The empty string is returned if the element type is not known. * * @param obj Object to get the label from. * @param flags The rendering flags * @return Returns the label or the empty string if the object type is not supported. */ public static String getTextLabel(Object obj, long flags) { return NewDartElementLabels.getTextLabel(obj, flags); } /** * Returns a label for a working set * * @param set the working set * @return the label of the working set */ public static String getWorkingSetLabel(IWorkingSet set) { return Strings.markLTR(set.getLabel()); } /** * Returns the styled string for the given resource. The returned label is BiDi-processed with * {@link TextProcessor#process(String, String)}. * * @param resource the resource * @return the styled string */ private static StyledString getStyledResourceLabel(IResource resource) { StyledString result = new StyledString(resource.getName()); return Strings.markLTR(result); } // private static void getFolderLabel(IPackageFragmentRoot root, long flags, // StringBuffer buf) { // IResource resource = root.getResource(); // boolean rootQualified = getFlag(flags, ROOT_QUALIFIED); // boolean referencedQualified = getFlag(flags, REFERENCED_ROOT_POST_QUALIFIED) // && isReferenced(root); // if (rootQualified) { // // buf.append(root.getPath().makeRelative().toString()); // // for libraries stored in our metadata area, just show the filename // IPath stateLocation = JavaScriptCore.getJavaScriptCore().getStateLocation(); // if (stateLocation.isPrefixOf(root.getPath())) { // buf.append(root.getPath().lastSegment().toString()); // } else { // buf.append(root.getPath().toString()); // } // } else { // if (resource != null) { // IPath projectRelativePath = resource.getProjectRelativePath(); // if (projectRelativePath.segmentCount() == 0) { // buf.append(resource.getName()); // referencedQualified = false; // } else { // buf.append(projectRelativePath.toString()); // } // } else // buf.append(root.getDisplayName()); // if (referencedQualified) { // buf.append(CONCAT_STRING); // buf.append(resource.getProject().getName()); // } else if (getFlag(flags, ROOT_POST_QUALIFIED)) { // buf.append(CONCAT_STRING); // buf.append(root.getParent().getDisplayName()); // } // } // } // private static void getInternalArchiveLabel(IPackageFragmentRoot root, // long flags, StringBuffer buf) { // IResource resource = root.getResource(); // boolean rootQualified = getFlag(flags, ROOT_QUALIFIED); // boolean referencedQualified = getFlag(flags, REFERENCED_ROOT_POST_QUALIFIED) // && isReferenced(root); // if (rootQualified) { // buf.append(root.getPath().makeRelative().toString()); // } else { // buf.append(root.getDisplayName()); // if (referencedQualified) { // buf.append(CONCAT_STRING); // buf.append(resource.getParent().getFullPath().makeRelative().toString()); // } else if (getFlag(flags, ROOT_POST_QUALIFIED)) { // buf.append(CONCAT_STRING); // buf.append(root.getParent().getPath().makeRelative().toString()); // } // } // } /** * Returns the styled string for the given storage. The returned label is BiDi-processed with * {@link TextProcessor#process(String, String)}. * * @param storage the storage * @return the styled string */ private static StyledString getStyledStorageLabel(IStorage storage) { StyledString result = new StyledString(storage.getName()); return Strings.markLTR(result); } @SuppressWarnings("unused") private static void getTypeArgumentSignaturesLabel(String[] typeArgsSig, long flags, StringBuffer buf) { if (typeArgsSig.length > 0) { buf.append('<'); for (int i = 0; i < typeArgsSig.length; i++) { if (i > 0) { buf.append(COMMA_STRING); } getTypeSignatureLabel(typeArgsSig[i], flags, buf); } buf.append('>'); } } @SuppressWarnings("unused") private static void getTypeParameterSignaturesLabel(String[] typeParamSigs, long flags, StringBuffer buf) { if (typeParamSigs.length > 0) { buf.append('<'); for (int i = 0; i < typeParamSigs.length; i++) { if (i > 0) { buf.append(COMMA_STRING); } // buf.append(Signature.getTypeVariable(typeParamSigs[i])); buf.append(typeParamSigs[i]); } buf.append('>'); } } private static void getTypeSignatureLabel(String typeSig, long flags, StringBuffer buf) { // int sigKind = Signature.getTypeSignatureKind(typeSig); // switch (sigKind) { // case Signature.BASE_TYPE_SIGNATURE: // buf.append(Signature.toString(typeSig)); // break; // case Signature.ARRAY_TYPE_SIGNATURE: // getTypeSignatureLabel(Signature.getElementType(typeSig), flags, buf); // for (int dim = Signature.getArrayCount(typeSig); dim > 0; dim--) { // buf.append('[').append(']'); // } // break; // case Signature.CLASS_TYPE_SIGNATURE: // String baseType = Signature.toString(typeSig); // // // @GINO: Anonymous UI Label // Util.insertTypeLabel( // Signature.getSimpleName(baseType), buf); // // getTypeArgumentSignaturesLabel(new String[0], flags, buf); // break; // default: // // unknown // } } // private static boolean getVariableLabel(IPackageFragmentRoot root, // long flags, StringBuffer buf) { // try { // IIncludePathEntry rawEntry = root.getRawIncludepathEntry(); // if (rawEntry != null // && rawEntry.getEntryKind() == IIncludePathEntry.CPE_VARIABLE) { // IPath path = rawEntry.getPath().makeRelative(); // if (getFlag(flags, REFERENCED_ROOT_POST_QUALIFIED)) { // int segements = path.segmentCount(); // if (segements > 0) { // buf.append(path.segment(segements - 1)); // if (segements > 1) { // buf.append(CONCAT_STRING); // buf.append(path.removeLastSegments(1).toOSString()); // } // } else { // buf.append(path.toString()); // } // } else { // buf.append(path.toString()); // } // buf.append(CONCAT_STRING); // if (root.isExternal()) // buf.append(root.getPath().toOSString()); // else // buf.append(root.getPath().makeRelative().toString()); // return true; // } // } catch (DartModelException e) { // DartToolsPlugin.log(e); // problems with class path // } // return false; // } /** * Returns <code>true</code> if the given package fragment root is referenced. This means it is * own by a different project but is referenced by the root's parent. Returns <code>false</code> * if the given root doesn't have an underlying resource. */ // private static boolean isReferenced(IPackageFragmentRoot root) { // IResource resource = root.getResource(); // if (resource != null) { // IProject jarProject = resource.getProject(); // IProject container = root.getJavaScriptProject().getProject(); // return !container.equals(jarProject); // } // return false; // } private DartElementLabels() { } }