|
What this is
Other links
The source code/* * Sun Public License Notice * * The contents of this file are subject to the Sun Public License * Version 1.0 (the "License"). You may not use this file except in * compliance with the License. A copy of the License is available at * http://www.sun.com/ * * The Original Code is NetBeans. The Initial Developer of the Original * Code is Sun Microsystems, Inc. Portions Copyright 1997-2003 Sun * Microsystems, Inc. All Rights Reserved. */ package org.netbeans.modules.editor.java; import java.awt.Dialog; import java.awt.event.ActionListener; import java.awt.event.ActionEvent; import java.lang.reflect.Modifier; import java.util.List; import java.util.Map; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.Iterator; import java.util.ResourceBundle; import java.util.StringTokenizer; import javax.swing.JButton; import javax.swing.SwingUtilities; import javax.swing.ImageIcon; import javax.swing.ListCellRenderer; import javax.swing.text.BadLocationException; import javax.swing.text.Document; import javax.swing.text.JTextComponent; import org.netbeans.api.java.classpath.ClassPath; import org.netbeans.editor.BaseDocument; import org.netbeans.editor.SyntaxSupport; import org.netbeans.editor.Utilities; import org.netbeans.editor.ext.Completion; import org.netbeans.editor.ext.CompletionQuery; import org.netbeans.editor.ext.ExtUtilities; import org.netbeans.editor.ext.java.JavaCompletion; import org.netbeans.editor.ext.java.JCClass; import org.netbeans.editor.ext.java.JCType; import org.netbeans.editor.ext.java.JCConstructor; import org.netbeans.editor.ext.java.JCMethod; import org.netbeans.editor.ext.java.JCField; import org.netbeans.editor.ext.java.JCParameter; import org.netbeans.editor.ext.java.JCFinder; import org.netbeans.editor.ext.java.JCCellRenderer; import org.netbeans.editor.ext.java.JCResultItem; import org.netbeans.modules.editor.NbEditorUtilities; import org.netbeans.spi.java.classpath.support.ClassPathSupport; import org.openide.src.ClassElement; import org.openide.src.ConstructorElement; import org.openide.src.MethodElement; import org.openide.src.FieldElement; import org.openide.src.Identifier; import org.openide.src.SourceElement; import org.openide.src.Type; import org.openide.src.MethodParameter; import org.openide.src.nodes.ElementNode; import org.openide.loaders.DataObject; import org.openide.loaders.DataFolder; import org.openide.nodes.Node; import org.openide.cookies.SourceCookie; import org.openide.filesystems.FileObject; import org.openide.DialogDescriptor; import org.openide.filesystems.FileStateInvalidException; import org.openide.filesystems.FileSystem; import org.openide.src.JavaDoc; import org.openide.src.JavaDocTag; import org.openide.util.enum.QueueEnumeration; /** * Extended Java Completion support * * @author Miloslav Metelka * @version 1.00 */ public class JCExtension { public static boolean equals(JCClass cls1, ClassElement cls2) { return cls1.getFullName().equals(cls2.getName().getFullName()); } public static boolean equals(JCType typ1, Type typ2) { // Get array depth of the type int arrayDepth = 0; while(typ2.isArray()) { arrayDepth++; typ2 = typ2.getElementType(); } String fn = typ2.isPrimitive() ? typ2.getFullString() : typ2.getClassName().getFullName(); return (typ1.getArrayDepth() == arrayDepth) && typ1.getClazz().getFullName().equals(fn); } public static boolean equals(JCField fld1, FieldElement fld2) { return fld1.getName().equals(fld2.getName().getFullName()) && equals(fld1.getType(), fld2.getType()); } public static boolean equals(JCConstructor ctr1, ConstructorElement ctr2) { JCParameter[] parms1 = ctr1.getParameters(); MethodParameter[] parms2 = ctr2.getParameters(); if (parms2 == null || parms1.length != parms2.length) { return false; } for (int i = parms1.length - 1; i >= 0; i--) { if (!equals(parms1[i].getType(), parms2[i].getType())) { return false; } } return true; } public static boolean equals(JCMethod mtd1, MethodElement mtd2) { return mtd1.getName().equals(mtd2.getName().getFullName()) && equals((JCConstructor)mtd1, (ConstructorElement)mtd2); } public static FieldElement findFieldElement(JCField fld, ClassElement ce) { FieldElement[] fes = ce.getFields(); if (fes != null) { for (int i = 0; i < fes.length; i++) { if (equals(fld, fes[i])) { return fes[i]; } } } return null; } public static ConstructorElement findConstructorElement(JCConstructor ctr, ClassElement ce) { ConstructorElement[] ces = ce.getConstructors(); if (ces != null) { for (int i = 0; i < ces.length; i++) { if (equals(ctr, ces[i])) { return ces[i]; } } } return null; } public static MethodElement findMethodElement(JCMethod mtd, ClassElement ce) { MethodElement[] mes = ce.getMethods(); if (mes != null) { for (int i = 0; i < mes.length; i++) { if (equals(mtd, mes[i])) { return mes[i]; } } } return null; } private static JCFinder getFinder(FileObject fo) { return JavaCompletion.getFinder(); } /** * Get or create the simple class from class element. * @param finder finder for searching class if necessary; cannot be * null if preferFinder is true * @param cp classpath on which the class can be searched if necessary; * cannot be null */ private static JCClass getIdentifierClass(ClassElement ce, Map lookupCache, boolean preferFinder, JCFinder finder, ClassPath cp) { String fn = ce.getName().getFullName(); // First try the lookupCache JCClass cls = (JCClass)lookupCache.get(fn); // check that class has a package - it is possible that it is already in cache // but with no package and in such a case the cache and class should be updated if (cls != null && cls.getPackageName() != null && cls.getPackageName().length() > 0) { return cls; } SourceElement se = ce.getSource(); if (se != null) { int pkgLen = 0; if (se.getPackage() != null) { pkgLen = se.getPackage().getFullName().length(); } cls = JavaCompletion.getSimpleClass(fn, pkgLen); lookupCache.put(fn, cls); return cls; } return getIdentifierClass(ce.getName(), lookupCache, preferFinder, finder, cp); } /** Get or create the simple class from identifier. * @param i identifier holding the class information * @param lookupCache cache holding the [name, simple-class] pairs for already found classes * @param preferFinder whether the package name finding should be first tried * through the finder or through the ClassElement.forName() * @param finder finder for searching class if necessary; cannot be * null if preferFinder is true * @param cp classpath on which the class can be searched if necessary; * cannot be null */ // PERF: do not use ClassElement.forName() to learn package name. // It is too expensive!! private static JCClass getIdentifierClass(Identifier i, Map lookupCache, boolean preferFinder, JCFinder finder, ClassPath cp) { String fn = i.getFullName(); // Get identifier's full name // First try the lookupCache JCClass cls = (JCClass)lookupCache.get(fn); if (cls != null) { return cls; } // Try finder if it's preferred if (preferFinder) { assert finder != null; cls = finder.getExactClass(fn); // try to find through the current finder if (cls != null) { cls = JavaCompletion.getSimpleClass(cls); // be sure to have simple class lookupCache.put(fn, cls); return cls; } } // try to find Identifier on classpath int pkgLen = getPackageLength(fn, cp); // If failed try to resolve through the current finder if (pkgLen < 0) { if (finder != null) { if (!preferFinder) { // already tried for preferFinder == true cls = finder.getExactClass(fn); } if (cls == null) { // not exact fullname, try by name only List clsList = finder.findClasses(null, fn, true); if (clsList != null && clsList.size() == 1) { // only when exactly one match cls = (JCClass)clsList.get(0); } } if (cls != null) { cls = JavaCompletion.getSimpleClass(cls); // be sure to have simple class lookupCache.put(fn, cls); return cls; } } } if (pkgLen < 0) { // ok, could not detect package length and so whole fully // qualified name will be used instead of just class name. pkgLen = 0; } // Get the class cls = JavaCompletion.getSimpleClass(fn, pkgLen); lookupCache.put(fn, cls); return cls; } /* DEBUG to getIdentifierClass() that test if the class is reachable if (pkgName != null && clsName != null) { try { // !!! Try to create the class without init Class.forName(pkgName + '.' + clsName.replace('.', '$'), false, JCExtension.class.getClassLoader()); } catch (ClassNotFoundException e) { System.out.println("Class not found: '" + pkgName + '.' + clsName + "', fn='" + fn + "'"); // NOI18N } } */ /** * Searches class on the classpath. The method searches existence of * .java or .class file on the classpath. It goes from the root of classpath * till it finds a corresponding file. * * @param name fully qualified class name; dot must be separator * @param cp classpath to use for class searching; cannot be null * @return length of the package or -1 if package could not be detected */ private static int getPackageLength(String name, ClassPath cp) { if (name.indexOf('.') == -1) { // default package return 0; } assert cp != null; List l = new ArrayList(); if (cp.getRoots().length > 0) { l.addAll(Arrays.asList(cp.getRoots())); } StringTokenizer tok = new StringTokenizer(name, "."); // NOI18N int pkgLen = 0; while (tok.hasMoreTokens()) { String nm = tok.nextToken(); Iterator it = l.iterator(); l = new ArrayList(); while (it.hasNext()) { FileObject fo = (FileObject)it.next(); if (fo.getFileObject(nm, "java") != null) { // NOI18N return pkgLen; } if (fo.getFileObject(nm, "class") != null) { // NOI18N return pkgLen; } FileObject f = fo.getFileObject(nm, null); if (f != null) { l.add(f); } } if (l.size() == 0) { return -1; } if (pkgLen == 0) { pkgLen += nm.length(); } else { pkgLen += nm.length() + 1; } } return -1; } private static JCType getType(Type t, Map lookupCache, boolean preferFinder, JCFinder finder, ClassPath cp) { // Get array depth of the type int arrayDepth = 0; while(t.isArray()) { arrayDepth++; t = t.getElementType(); } JCClass c; if (t.isPrimitive()) { c = JavaCompletion.getPrimitiveClass(t.getFullString()); } else { c = getIdentifierClass(t.getClassName(), lookupCache, preferFinder, finder, cp); } return JavaCompletion.getType(c, arrayDepth); } /** * Returns one classpath which is merge of SOURCE, COMPILE and BOOT * classpaths of the given file object. */ public static ClassPath getFullClassPath(FileObject context) { ArrayList l = new ArrayList(); ClassPath cp = ClassPath.getClassPath(context, ClassPath.SOURCE); if (cp != null) { l.add(cp); } cp = ClassPath.getClassPath(context, ClassPath.COMPILE); if (cp != null) { l.add(cp); } cp = ClassPath.getClassPath(context, ClassPath.BOOT); if (cp != null) { l.add(cp); } return ClassPathSupport.createProxyClassPath((ClassPath[])l.toArray(new ClassPath[l.size()])); } /** Finds an inner class with the same name as the resultClassItem */ static JCClass findResultInnerClass(JCFinder finder, JCClass topClass, String innerClsName, Document doc){ if (topClass == null || innerClsName == null) return null; ClassElement ce = ClassElement.forName(topClass.getFullName(), NbEditorUtilities.getDataObject (doc).getPrimaryFile()); if (ce == null) return null; ClassElement innerClasses[] = ce.getClasses(); if (innerClsName != null){ for (int i=0; i |
... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse
URI on this website is
paid back to open source projects.