package com.redhat.ceylon.eclipse.code.search; import static com.redhat.ceylon.eclipse.code.preferences.CeylonPreferenceInitializer.PARAMS_IN_OUTLINES; import static com.redhat.ceylon.eclipse.code.preferences.CeylonPreferenceInitializer.PARAM_TYPES_IN_OUTLINES; import static com.redhat.ceylon.eclipse.code.preferences.CeylonPreferenceInitializer.RETURN_TYPES_IN_OUTLINES; import static com.redhat.ceylon.eclipse.util.Highlights.ARROW_STYLER; import static com.redhat.ceylon.eclipse.util.Highlights.ID_STYLER; import static com.redhat.ceylon.eclipse.util.Highlights.KW_STYLER; import static com.redhat.ceylon.eclipse.util.Highlights.PACKAGE_STYLER; import static com.redhat.ceylon.eclipse.util.Highlights.TYPE_ID_STYLER; import static com.redhat.ceylon.eclipse.util.Highlights.styleJavaType; import static com.redhat.ceylon.eclipse.util.InteropUtils.toCeylonString; import static com.redhat.ceylon.eclipse.util.InteropUtils.toJavaString; import static org.eclipse.jdt.core.IJavaElement.PACKAGE_FRAGMENT; import static org.eclipse.jdt.core.IJavaElement.PACKAGE_FRAGMENT_ROOT; import static org.eclipse.jdt.core.IJavaElement.TYPE; import static org.eclipse.jdt.core.Signature.getSignatureSimpleName; import static org.eclipse.jface.viewers.StyledString.COUNTER_STYLER; import org.eclipse.core.runtime.IPath; import org.eclipse.jdt.core.Flags; import org.eclipse.jdt.core.IField; import org.eclipse.jdt.core.IJavaElement; import org.eclipse.jdt.core.IMember; import org.eclipse.jdt.core.IMethod; import org.eclipse.jdt.core.IPackageFragment; import org.eclipse.jdt.core.IPackageFragmentRoot; import org.eclipse.jdt.core.IType; import org.eclipse.jdt.core.JavaModelException; import org.eclipse.jdt.internal.compiler.env.IBinaryType; import org.eclipse.jdt.internal.core.BinaryType; import org.eclipse.jdt.internal.core.JarPackageFragmentRoot; import org.eclipse.jdt.internal.core.PackageFragment; import org.eclipse.jdt.internal.core.SourceType; import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.jface.viewers.StyledString; import org.eclipse.swt.graphics.Image; import com.redhat.ceylon.eclipse.code.outline.CeylonLabelProvider; import com.redhat.ceylon.eclipse.core.builder.CeylonBuilder; import com.redhat.ceylon.eclipse.ui.CeylonPlugin; import com.redhat.ceylon.eclipse.util.Highlights; import com.redhat.ceylon.ide.common.model.BaseIdeModule; import com.redhat.ceylon.ide.common.model.CeylonBinaryUnit; import com.redhat.ceylon.ide.common.model.IJavaModelAware; import com.redhat.ceylon.ide.common.model.IdeUnit; import com.redhat.ceylon.ide.common.model.JavaClassFile; import com.redhat.ceylon.model.typechecker.model.Module; import com.redhat.ceylon.model.typechecker.model.Package; public class SearchResultsLabelProvider extends CeylonLabelProvider { @Override public Image getImage(Object element) { if (element instanceof WithCategory) { WithCategory wsf = (WithCategory) element; element = wsf.getItem(); } if (element instanceof WithSourceFolder) { WithSourceFolder wsf = (WithSourceFolder) element; element = wsf.element; } String key; int decorations; if (element instanceof CeylonSearchMatch.Type) { key = CEYLON_SEARCH; decorations = 0; // return null; } else if (element instanceof ArchiveMatches) { key = RUNTIME_OBJ; decorations = 0; } else if (element instanceof CeylonElement) { CeylonElement ce = (CeylonElement) element; key = ce.getImageKey(); decorations = ce.getDecorations(); } else if (element instanceof IType || element instanceof IField || element instanceof IMethod) { IJavaElement je = (IJavaElement) element; key = getImageKeyForDeclaration(je); decorations = 0; } else if (element instanceof IJavaModelAware && element instanceof IdeUnit) { IdeUnit unit = (IdeUnit) element; String sourceFileName = toJavaString(unit.getSourceFileName()); if (sourceFileName != null && sourceFileName.endsWith("java")) { key = JAVA_FILE; decorations = 0; } else if (sourceFileName == null && unit.getCeylonModule().isJava()) { key = JAVA_CLASS_FILE; decorations = 0; } else { key = super.getImageKey(element); decorations = super.getDecorationAttributes(element); } } else { key = super.getImageKey(element); decorations = super.getDecorationAttributes(element); } return getDecoratedImage(key, decorations, false); } @Override public StyledString getStyledText(Object element) { if (element instanceof WithCategory) { WithCategory wc = (WithCategory) element; element = wc.getItem(); } if (element instanceof WithSourceFolder) { WithSourceFolder wsf = (WithSourceFolder) element; element = wsf.element; } if (element instanceof CeylonSearchMatch.Type) { return new StyledString(element.toString(), Highlights.ARROW_STYLER); } if (element instanceof ArchiveMatches) { return new StyledString("Source Archive Matches"); } else if (element instanceof CeylonElement) { CeylonElement ce = (CeylonElement) element; return getStyledLabelForSearchResult(ce); } else if (element instanceof IType || element instanceof IField|| element instanceof IMethod) { IJavaElement je = (IJavaElement) element; return getStyledLabelForSearchResult(je); } else if (element instanceof Module || element instanceof Package || element instanceof IPackageFragment || element instanceof IPackageFragmentRoot) { StyledString text = super.getStyledText(element); StyledString styledString = new StyledString(text.toString()); if (appendSourceLocation()) { String path = null; if (element instanceof BaseIdeModule) { BaseIdeModule mod = (BaseIdeModule) element; path = toJavaString(mod.getSourceArchivePath()); } else if (element instanceof JarPackageFragmentRoot) { try { IPackageFragmentRoot pfr = (IPackageFragmentRoot) element; IPath sap = pfr.getSourceAttachmentPath(); if (sap!=null) { path = sap.toPortableString(); } } catch (JavaModelException e) { e.printStackTrace(); } } if (path!=null) { styledString.append(" \u2014 " + path, COUNTER_STYLER); } } return styledString; } else if (element instanceof IdeUnit) { IdeUnit unit = (IdeUnit) element; String displayedFileName = toJavaString(unit.getSourceFileName()); if (displayedFileName == null) { displayedFileName = unit.getFilename(); } return new StyledString(displayedFileName); } else { return super.getStyledText(element); } } boolean appendMatchPackage() { return true; } boolean appendSourceLocation() { return true; } private StyledString getStyledLabelForSearchResult( CeylonElement ce) { StyledString label = ce.getLabel(); if (appendMatchPackage()) { StyledString fullLabel = new StyledString().append(label) .append(" \u2014 " + ce.getPackageLabel(), PACKAGE_STYLER); if (appendSourceLocation()) { fullLabel.append(" \u2014 " + ce.getPathString(), COUNTER_STYLER); } return fullLabel; } else { return label; } } private StyledString getStyledLabelForSearchResult( IJavaElement je) { StyledString styledString = new StyledString(); String name = je.getElementName(); IPreferenceStore prefs = CeylonPlugin.getPreferences(); if (je instanceof IMethod) { IMethod m = (IMethod) je; try { String returnType = m.getReturnType(); if (returnType.equals("V")) { styledString.append("void", KW_STYLER); } else { styledString.append("method", KW_STYLER); /*styleJavaType(styledString, getSignatureSimpleName(returnType));*/ } } catch (Exception e) { e.printStackTrace(); } styledString.append(' '); IJavaElement parent = je.getParent(); if (parent instanceof IType) { styledString.append(parent.getElementName(), TYPE_ID_STYLER) .append('.'); } styledString.append(name, ID_STYLER); boolean names = prefs.getBoolean(PARAMS_IN_OUTLINES); boolean types = prefs.getBoolean(PARAM_TYPES_IN_OUTLINES); if (names || types) { try { styledString.append('('); String[] parameterTypes = m.getParameterTypes(); String[] parameterNames = m.getParameterNames(); boolean first = true; for (int i=0; i<parameterTypes.length && i<parameterNames.length; i++) { if (first) { first = false; } else { styledString.append(", "); } if (types) { styleJavaType(styledString, getSignatureSimpleName( parameterTypes[i])); } if (types&&names) { styledString.append(' '); } if (names) { styledString.append(parameterNames[i], ID_STYLER); } } styledString.append(')'); } catch (Exception e) { e.printStackTrace(); } } if (prefs.getBoolean(RETURN_TYPES_IN_OUTLINES)) { try { String returnType = m.getReturnType(); styledString.append(" ∊ "); styleJavaType(styledString, getSignatureSimpleName(returnType), ARROW_STYLER); } catch (Exception e) { e.printStackTrace(); } } } else if (je instanceof IField) { styledString.append("field", KW_STYLER); /*try { String type = ((IField) je).getTypeSignature(); styleJavaType(styledString, getSignatureSimpleName(type)); } catch (Exception e) { e.printStackTrace(); }*/ styledString.append(' ') .append(name, ID_STYLER); if (prefs.getBoolean(RETURN_TYPES_IN_OUTLINES)) { try { IField f = (IField) je; String type = f.getTypeSignature(); styledString.append(" ∊ "); styleJavaType(styledString, getSignatureSimpleName(type), ARROW_STYLER); } catch (Exception e) { e.printStackTrace(); } } } else if (je instanceof IType) { IType type = (IType) je; try { if (type.isAnnotation()) { styledString.append('@') .append("interface ", KW_STYLER); } else if (type.isInterface()) { styledString.append("interface ", KW_STYLER); } else if (type.isClass()) { styledString.append("class ", KW_STYLER); } else if (type.isEnum()) { styledString.append("enum ", KW_STYLER); } } catch (Exception e) { e.printStackTrace(); } styledString.append(name, TYPE_ID_STYLER); } if (appendMatchPackage()) { IPackageFragment pkg = (IPackageFragment) je.getAncestor(PACKAGE_FRAGMENT); styledString.append(" \u2014 ", PACKAGE_STYLER) .append(pkg.getElementName(), PACKAGE_STYLER); if (appendSourceLocation()) { try { IType type = (IType) je.getAncestor(TYPE); @SuppressWarnings("rawtypes") IJavaModelAware unit = CeylonBuilder.getUnit(type); if (unit instanceof CeylonBinaryUnit) { @SuppressWarnings("rawtypes") CeylonBinaryUnit bu = (CeylonBinaryUnit)unit; String fullPath = toJavaString(bu.getSourceFullPath()); if (fullPath != null) { return styledString.append( " \u2014 " + fullPath, COUNTER_STYLER); } } if (unit instanceof JavaClassFile) { @SuppressWarnings("rawtypes") JavaClassFile javaClassFile = (JavaClassFile) unit; BaseIdeModule module = javaClassFile.getCeylonModule(); if (module.getIsCeylonBinaryArchive()) { String sourceRelativePath = sourceRelativePath( javaClassFile, module); String sourceArchivePath = toJavaString(module.getSourceArchivePath()); if (sourceRelativePath != null && sourceArchivePath != null) { return styledString.append( " \u2014 " + sourceArchivePath + "!/" + sourceRelativePath, COUNTER_STYLER); } } } IPackageFragmentRoot root = (IPackageFragmentRoot) je.getAncestor( PACKAGE_FRAGMENT_ROOT); if (type instanceof BinaryType) { BinaryType bt = (BinaryType) type; IBinaryType info = (IBinaryType) bt.getElementInfo(); String simpleSourceFileName = bt.getSourceFileName(info); PackageFragment pkgFrag = (PackageFragment) type.getPackageFragment(); IPath sourceArchivePath = root.getSourceAttachmentPath(); IPath sourceFolderPath = root.getSourceAttachmentRootPath(); if (sourceArchivePath != null && sourceFolderPath != null) { IPath subpath = sourceFolderPath.makeAbsolute(); for (String pn: pkgFrag.names) { subpath = subpath.append(pn); } subpath.append(simpleSourceFileName); return styledString.append( " \u2014 " + sourceArchivePath.toPortableString() + "!" + subpath.toPortableString(), COUNTER_STYLER); } } else if (type instanceof SourceType) { String fullPath = type.getCompilationUnit() .getCorrespondingResource() .getFullPath() .toPortableString(); return styledString.append( " \u2014 " + fullPath, COUNTER_STYLER); } //new SourceMapper(root.getSourceAttachmentPath(), root.getSourceAttachmentRootPath()==null ? null : root.getSourceAttachmentRootPath().toString(), null) //.findSource(t, info); } catch (Exception e) { e.printStackTrace(); } } } return styledString; } private static String sourceRelativePath( @SuppressWarnings("rawtypes") JavaClassFile javaClassFile, BaseIdeModule module) { ceylon.language.String path = toCeylonString(javaClassFile.getRelativePath()); return toJavaString(module.toSourceUnitRelativePath(path)); } private static String getImageKeyForDeclaration( IJavaElement e) { if (e==null) return null; boolean shared = false; if (e instanceof IMember) { try { IMember m = (IMember) e; shared = Flags.isPublic(m.getFlags()); } catch (JavaModelException jme) { jme.printStackTrace(); } } switch(e.getElementType()) { case IJavaElement.METHOD: if (shared) { return CEYLON_METHOD; } else { return CEYLON_LOCAL_METHOD; } case IJavaElement.FIELD: if (shared) { return CEYLON_ATTRIBUTE; } else { return CEYLON_LOCAL_ATTRIBUTE; } case IJavaElement.TYPE: if (shared) { return CEYLON_CLASS; } else { return CEYLON_LOCAL_CLASS; } default: return null; } } }