Source Code Cross Referenced for CompletionManager.java in  » IDE » tIDE » tide » editor » completions » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » IDE » tIDE » tide.editor.completions 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        package tide.editor.completions;
0002:
0003:        import tide.editor.*;
0004:        import tide.utils.*;
0005:        import tide.syntaxtree.*;
0006:        import tide.sources.*;
0007:        import tide.classsyntax.*;
0008:        import javaparser.*;
0009:        import snow.texteditor.*;
0010:        import javax.swing.*;
0011:        import javax.swing.event.*;
0012:        import javax.swing.text.*;
0013:        import java.util.*;
0014:        import java.util.regex.*;
0015:        import java.awt.EventQueue;
0016:        import java.awt.Point;
0017:        import java.awt.Rectangle;
0018:        import java.awt.event.*;
0019:
0020:        /** Some delegated inserts called from the EditorDocumentFilter.
0021:         *   may popup some completion proposal dialogs in certain cases.
0022:         *   (on CTRL+space, CTRL+T, dot, ampersand, ...)
0023:         *
0024:         *  TODO: wait some 200ms and only popup if nothing else was typed...
0025:         *  TODO: ctrl+space ignores already typed items (for attributes)
0026:         */
0027:        public class CompletionManager {
0028:            final EditorPanel editor;
0029:
0030:            public final boolean allowLazyInexactSearch = false; // maybe later, but should show an hint !
0031:
0032:            // only contains the arguments completions dialogs (not modal)
0033:            final ArrayList<CompletionDialog> openedDialogs = new ArrayList<CompletionDialog>();
0034:
0035:            public CompletionManager(EditorPanel editor) {
0036:                this .editor = editor;
0037:            }
0038:
0039:            /** Called when changing source in the editor panel.
0040:             */
0041:            public void closeOpenedDialogs() {
0042:                for (int i = openedDialogs.size() - 1; i >= 0; i--) //reverse
0043:                {
0044:                    CompletionDialog cd = openedDialogs.get(i);
0045:                    cd.cancelDialog();
0046:                    openedDialogs.remove(cd);
0047:                }
0048:            }
0049:
0050:            /** called when "esc" pressed in the editor
0051:             */
0052:            public void closeLastCompletionDialog() {
0053:                int n = openedDialogs.size();
0054:                if (n > 0) {
0055:                    CompletionDialog cd = openedDialogs.get(n - 1);
0056:                    cd.cancelDialog();
0057:                    openedDialogs.remove(cd);
0058:                }
0059:            }
0060:
0061:            /** Shows all types in the project and libs
0062:             *   (TODO: look at name starting with typed text fragment before position if any)
0063:             */
0064:            public void controlTPressed(FileItem editedSource,
0065:                    SimpleDocument doc, int posInSource, boolean projectOnly,
0066:                    final String initialTextForBrowseMode) {
0067:                Rectangle posPt; // = new Rectangle(0,0,10,10);
0068:                try {
0069:                    posPt = editor.getTextPane().modelToView(posInSource);
0070:                    Point pts = editor.getTextPane().getLocationOnScreen();
0071:                    ImportCompletionDialog acd = new ImportCompletionDialog(
0072:                            true, MainEditorFrame.instance,
0073:                            (int) (pts.getX() + posPt.getX()), (int) (pts
0074:                                    .getY()
0075:                                    + posPt.getY() + editor.getTextPane()
0076:                                    .getFont().getSize()), editor.getTextPane()
0077:                                    .getDocument(), posInSource, projectOnly,
0078:                            initialTextForBrowseMode);
0079:
0080:                    if (!acd.getWasCancelled()
0081:                            && initialTextForBrowseMode == null) {
0082:                        String sel = acd.getSelectionAndClear();
0083:                        doc.insertString(sel, posInSource);
0084:                    }
0085:                } catch (Exception e) {
0086:                    e.printStackTrace();
0087:                }
0088:            }
0089:
0090:            public void dotWithoutCompletion(FileItem editedSource,
0091:                    SimpleDocument doc, int posInSource) {
0092:                if (editedSource == null)
0093:                    return;
0094:                if (!editedSource.isEditable())
0095:                    return;
0096:                try {
0097:                    doc.insertString(".", posInSource);
0098:                } catch (Exception e) {
0099:                    e.printStackTrace();
0100:                }
0101:            }
0102:
0103:            /** Completion with local variables.
0104:             *  (like "this" plus local variables) + types starting with
0105:             *  TODO: better use scopes (let CTRL+ space trigger other completions... ??)
0106:             */
0107:            public void controlSpacePressed(final FileItem editedSource,
0108:                    final SimpleDocument doc, final int posInSource) {
0109:                // TODO: with the new parser
0110:                SimplifiedSyntaxTree2 sst = editedSource
0111:                        .getSimplifiedSyntaxTreeIfAlreadyMade();
0112:                if (sst == null)
0113:                    return;
0114:
0115:                // can be used when already typing some incomplete ID
0116:                final ParsedID pid = SyntaxUtils.getJavaIdentifierBefore(doc,
0117:                        posInSource, "this"); // [Feb2008] to really enforce "this" + dot
0118:                final SingleClassLoader scl = SingleClassLoader
0119:                        .createSingleClassLoader();
0120:                final IDChain resolver = new IDChain(pid, editedSource, doc,
0121:                        posInSource, ".", scl);
0122:
0123:                final int[] lineCol = DocumentUtils.getLineColumnNumbers(doc,
0124:                        posInSource);
0125:                //TypeInterface deepestTypeAtPos = sst.getDeepestTypeAt(lineCol[0]+1, lineCol[1]+1, true);
0126:                RAWParserTreeNode tokenAtOrAfterPosition = TreeUtils
0127:                        .getTokenNodeAtOrAfterPosition(
0128:                                sst.getRawParserResult(), lineCol[0],
0129:                                lineCol[1]);
0130:                List<Parameter> params = new ArrayList<Parameter>();
0131:                TreeUtils.collectLocalVariablesBefore(tokenAtOrAfterPosition,
0132:                        lineCol[0], params);
0133:                List<AttrCompletionItem> av = new ArrayList<AttrCompletionItem>();
0134:                Set<String> alreadyAddedNames = new HashSet<String>();
0135:                for (Parameter p : params) {
0136:                    if (!alreadyAddedNames.contains(p.name)) {
0137:                        av.add(AttrCompletionItem.createParameter(p.name,
0138:                                p.type));
0139:                        alreadyAddedNames.add(p.name);
0140:                    }
0141:                }
0142:
0143:                // [Jan2007]: look at eventual classes starting with that name !
0144:                //
0145:                String start = pid.identifierChain;
0146:                if (start.length() > 0) // && Character.isUpperCase(start.charAt(0)))
0147:                {
0148:                    MainEditorFrame.debugOut("invalid resolver, looking for "
0149:                            + start);
0150:                    List<FileItem> hits = TypeLocator
0151:                            .searchSimpleNamesStartingWith(start);
0152:                    for (FileItem fi : hits) {
0153:                        av.add(AttrCompletionItem.createNameCompletionForClass(
0154:                                fi, start));
0155:                    }
0156:                }
0157:
0158:                // [Feb2007]: add the members of this class.
0159:                // [Feb2008]: use the real type at caret. the one ot "this."
0160:                // [Feb2008]: put the code in a method, to share with CtrlSpace action
0161:                String resolvedClassName = editedSource.getJavaName();
0162:                if (resolver != null
0163:                        && resolver.getLastChainComponent() != null) {
0164:                    resolvedClassName = resolveClassName(editedSource, resolver
0165:                            .getLastChainComponent(), scl);
0166:                }
0167:
0168:                //System.out.println("Add attrs for "+resolvedClassName);
0169:                if (resolvedClassName != null) {
0170:                    boolean onlyStatic = false;
0171:                    av.addAll(ClassSyntaxManager.getAttributes(scl,
0172:                            resolvedClassName, null, true, true, true,
0173:                            onlyStatic));
0174:                }
0175:
0176:                try {
0177:                    Rectangle posPt = editor.getTextPane().modelToView(
0178:                            posInSource);
0179:                    Point pts = editor.getTextPane().getLocationOnScreen();
0180:
0181:                    //TODO: look at class name and edited class name to decide if package scope enabled...
0182:
0183:                    final AttributeCompletionDialog acd = new AttributeCompletionDialog(
0184:                            MainEditorFrame.instance, (int) (pts.getX() + posPt
0185:                                    .getX()),
0186:                            (int) (pts.getY() + posPt.getY() + editor
0187:                                    .getTextPane().getFont().getSize()), doc,
0188:                            posInSource, "Local variables completion (+ "
0189:                                    + resolvedClassName + ")", false); // show also private...
0190:
0191:                    acd.setCompletionItems(av);
0192:                    acd.addFactoryBarForCTRLSpaceCompletion();
0193:                    acd.setVisible(true); // MODAL !
0194:
0195:                    String specialCompletionPrepend = acd
0196:                            .getSpecialCompletionPrepend();
0197:                    int rewind = acd.caretRewind;
0198:
0199:                    doc.insertString(acd.getSelectionAndClear(), posInSource);
0200:
0201:                    if (specialCompletionPrepend != null
0202:                            && specialCompletionPrepend.length() > 0) {
0203:                        doc.insertString(specialCompletionPrepend, posInSource);
0204:                    }
0205:
0206:                    if (rewind != 0) {
0207:                        editor.getTextPane().setCaretPosition(
0208:                                editor.getTextPane().getCaretPosition()
0209:                                        - rewind);
0210:                    }
0211:                } catch (Exception e) {
0212:                    e.printStackTrace();
0213:                }
0214:            }
0215:
0216:            /** when @ is pressed, propose some javadoc OR annotations
0217:                @return the replaced text
0218:             */
0219:            public String ampersandPressed(DocumentFilter.FilterBypass fb,
0220:                    int offset, int length, AttributeSet attrs)
0221:                    throws Exception {
0222:                Document doc = editor.getTextPane().getDocument();
0223:                boolean inComment = false;
0224:                boolean inString = false;
0225:                //Vector<String>[] args = null;
0226:                String preceedingTokenOfInterrest = "";
0227:                try {
0228:                    String txtUpto = doc.getText(0, offset);
0229:                    inString = SyntaxUtils.isInString(txtUpto, offset);
0230:                    if (inString) {
0231:                        fb.replace(offset, 0, "@", attrs);
0232:                        return "@";
0233:                    }
0234:                    inComment = SyntaxUtils.isInComment(txtUpto, offset);
0235:                    if (txtUpto.endsWith("{"))
0236:                        preceedingTokenOfInterrest = "{";
0237:                    if (txtUpto.endsWith("//"))
0238:                        preceedingTokenOfInterrest = "//"; //JML
0239:                } catch (RuntimeException ignore) {
0240:                }
0241:
0242:                try {
0243:                    Rectangle posPt = editor.getTextPane().modelToView(offset);
0244:                    Point pts = editor.getTextPane().getLocationOnScreen();
0245:
0246:                    AmpersandCompletionDialog acd = new AmpersandCompletionDialog(
0247:                            inComment, MainEditorFrame.instance, (int) (pts
0248:                                    .getX() + posPt.getX()), (int) (pts.getY()
0249:                                    + posPt.getY() + editor.getTextPane()
0250:                                    .getFont().getSize()), editor.getTextPane()
0251:                                    .getDocument(), offset,
0252:                            preceedingTokenOfInterrest);
0253:
0254:                    String repl = "";
0255:                    if (!acd.getWasCancelled()) {
0256:                        repl = acd.getSelection();
0257:                    } else {
0258:                        repl = "@";
0259:                    }
0260:
0261:                    fb.replace(offset, length, repl, attrs);
0262:                    return repl;
0263:
0264:                } catch (Exception e) {
0265:                    throw e;
0266:                }
0267:
0268:                //return "";
0269:
0270:            }
0271:
0272:            /** Either shows the methods  "xxx(..." or the constructors "Xxx(..."
0273:             */
0274:            public String openingParenthesisPressed(FileItem editedSource,
0275:                    DocumentFilter.FilterBypass fb, int offset, int length,
0276:                    AttributeSet attrs) throws Exception {
0277:
0278:                if (isInStringOrComment(offset)) {
0279:                    try {
0280:                        fb.replace(offset, length, "(", attrs);
0281:                    } catch (Exception e) {
0282:                        e.printStackTrace();
0283:                    }
0284:                    return "(";
0285:                }
0286:
0287:                SimpleDocument doc = editor.getDocument();
0288:
0289:                final SingleClassLoader scl = SingleClassLoader
0290:                        .createSingleClassLoader();
0291:
0292:                // detect the identifier before offset
0293:                // this is trimmed and without spaces. ex: System.out.println
0294:                //   or  a().re[][] , with empty parenthesis and brackets...
0295:                ParsedID pid = SyntaxUtils.getJavaIdentifierBefore(doc, offset,
0296:                        null);
0297:                final IDChain resolver = new IDChain(pid, editedSource, doc,
0298:                        offset, "(", scl);
0299:
0300:                String id = pid.identifierChain;
0301:                MainEditorFrame
0302:                        .debugOut("\n===== Arguments resolver =====:\nid>>> "
0303:                                + resolver + " <<<");
0304:
0305:                String repl = "(";
0306:
0307:                if ("@".equals(pid.precedingItem)) {
0308:
0309:                    repl = "(";
0310:                    try {
0311:                        // just replace...
0312:                        fb.replace(offset, length, repl, attrs);
0313:
0314:                        Class clazz = resolver.getClassForType(resolver
0315:                                .getLastChainComponent());
0316:                        if (clazz != null) {
0317:                            Rectangle posPt = editor.getTextPane().modelToView(
0318:                                    offset);
0319:                            Point pts = editor.getTextPane()
0320:                                    .getLocationOnScreen();
0321:
0322:                            final AnnotationParamsCompletion acd = new AnnotationParamsCompletion(
0323:                                    clazz,
0324:                                    "Annotation arguments completion for "
0325:                                            + clazz.getName(),
0326:                                    MainEditorFrame.instance,
0327:                                    (int) (pts.getX() + posPt.getX()) - 50,
0328:                                    (int) (pts.getY() + posPt.getY() + editor
0329:                                            .getTextPane().getFont().getSize()) + 5,
0330:                                    this , offset);
0331:                            openedDialogs.add(acd);
0332:                        }
0333:
0334:                    } catch (Exception e) {
0335:                        e.printStackTrace();
0336:                    }
0337:                    return repl;
0338:                }
0339:
0340:                //   String className = null;
0341:                //  FileItem foundType = null;
0342:
0343:                /*   boolean staticOnly = false;
0344:                   boolean includePrivate = false;
0345:                   boolean includeProtected = false;
0346:                   boolean includePackageScope = false;
0347:                   boolean constructorMode = false;*/
0348:
0349:                if (resolver != null && resolver.isValid()) {
0350:                    final IDChainElement elt = resolver.getLastChainComponent();
0351:
0352:                    /*
0353:                    className = id;
0354:                    foundType = locateTypeUsingImports(null, className, editedSource.getPackageName(), allowLazyInexactSearch);
0355:
0356:                      includePrivate = foundType.getJavaName().equals( editedSource.getJavaName());
0357:                      includeProtected = includePrivate;  // TODO:
0358:                      includePackageScope = foundType.getPackageName().equals( editedSource.getPackageName());
0359:                     */
0360:                    Rectangle posPt = editor.getTextPane().modelToView(offset);
0361:                    Point pts = editor.getTextPane().getLocationOnScreen();
0362:
0363:                    //TODO: look at class name and edited class name to decide if package scope enabled...
0364:
0365:                    //System.out.println("acd showing !");
0366:                    final ArgumentsCompletionDialog acd = new ArgumentsCompletionDialog(
0367:                            "Arguments completion", MainEditorFrame.instance,
0368:                            (int) (pts.getX() + posPt.getX()) - 50, (int) (pts
0369:                                    .getY()
0370:                                    + posPt.getY() + editor.getTextPane()
0371:                                    .getFont().getSize()) + 5, this , offset);
0372:                    openedDialogs.add(acd);
0373:
0374:                    // not modal !
0375:                    editor.getTextPane().requestFocus();
0376:
0377:                    final Thread t = new Thread() {
0378:                        public void run() {
0379:                            List<AttrCompletionItem> av = null;
0380:
0381:                            if (elt.getKind() == ElementKind.Constructor) {
0382:                                MainEditorFrame
0383:                                        .debugOut("\n=====Constructor completion, "
0384:                                                + elt.getName());
0385:                                MainEditorFrame.debugOut("type="
0386:                                        + elt.getTypeMaybeResolved());
0387:                                final String className = elt
0388:                                        .getTypeMaybeResolved();
0389:
0390:                                if (className != null) {
0391:                                    final String tp = elt.getTypeParameters();
0392:                                    final StringBuilder paramsMapperText = new StringBuilder();
0393:                                    av = ClassSyntaxManager
0394:                                            .getConstructorsArgs(scl,
0395:                                                    className, tp, true, true,
0396:                                                    true, // show all...
0397:                                                    false, // not static only
0398:                                                    paramsMapperText);
0399:                                    EventQueue.invokeLater(new Runnable() {
0400:                                        public void run() {
0401:                                            acd.setTitle("Constructor of "
0402:                                                    + className
0403:                                                    + (tp != null ? " <"
0404:                                                            + paramsMapperText
0405:                                                            + ">" : ""));
0406:                                        }
0407:                                    });
0408:
0409:                                }
0410:                            } else if (elt.getKind() == ElementKind.Method) {
0411:                                //System.out.println("method completion");
0412:                                // null ??
0413:                                //System.out.println("method completion res type "+elt.resolvedType);
0414:
0415:                                final String className;
0416:                                String classParameters = null;
0417:                                if (resolver.chain.size() > 1) {
0418:                                    // the last is the method => the preceeding is the class
0419:                                    IDChainElement idce = resolver.chain
0420:                                            .get(resolver.chain.size() - 2);
0421:                                    className = idce.getTypeMaybeResolved();
0422:                                    classParameters = idce.getTypeParameters();
0423:                                } else {
0424:                                    // ??? direct call from the method (TODO: look at enclosing class)
0425:                                    className = resolver.source.getJavaName();
0426:                                }
0427:
0428:                                if (className != null) {
0429:                                    final String title = "Method "
0430:                                            + elt.getName()
0431:                                            + " in "
0432:                                            + className
0433:                                            + (classParameters != null ? " <"
0434:                                                    + classParameters + ">"
0435:                                                    : "");
0436:                                    EventQueue.invokeLater(new Runnable() {
0437:                                        public void run() {
0438:                                            acd.setTitle(title);
0439:                                        }
0440:                                    });
0441:
0442:                                    av = ClassSyntaxManager.getMethodsArgs(scl,
0443:                                            className, elt.getName(),
0444:                                            classParameters, true, true, true,
0445:                                            false);
0446:                                }
0447:                            } else if (elt.getKind() == ElementKind.Class) {
0448:                                MainEditorFrame
0449:                                        .debugOut("Unknown type, no parent completion for class element="
0450:                                                + elt);
0451:                                MainEditorFrame
0452:                                        .debugOut("details: " + resolver);
0453:                            } else {
0454:                                MainEditorFrame
0455:                                        .debugOut("Unknown type, no parent completion for type="
0456:                                                + elt.getKind());
0457:                                MainEditorFrame
0458:                                        .debugOut("details: " + resolver);
0459:                            }
0460:
0461:                            if (av != null && av.size() > 0) {
0462:                                acd.setCompletionItems(av);
0463:                            } else {
0464:                                EventQueue.invokeLater(new Runnable() {
0465:                                    public void run() {
0466:                                        MainEditorFrame
0467:                                                .debugOut("cancel arg compl dialog");
0468:                                        acd.cancelDialog();
0469:                                    }
0470:                                });
0471:                            }
0472:                        }
0473:                    };
0474:                    t.setName("AttributesCompletion:names");
0475:                    t.setPriority(Thread.NORM_PRIORITY - 1);
0476:                    t.start();
0477:
0478:                } else {
0479:                    System.out.println("opening parenthesis was no resolved");
0480:                }
0481:
0482:                fb.replace(offset, length, "(", attrs);
0483:                return "(";
0484:            }
0485:
0486:            /** space pressed.
0487:             * => import completion if import preceeds.
0488:             */
0489:            public String spacePressed(DocumentFilter.FilterBypass fb,
0490:                    int offset, int length, AttributeSet attrs)
0491:                    throws Exception {
0492:                // look if "import" preceed the offset
0493:                String replacement = "";
0494:                boolean importFound = false;
0495:                if (offset > 6) {
0496:                    try {
0497:                        String txt = editor.getDocument()
0498:                                .getText(offset - 6, 6);
0499:                        //System.out.println(""+txt);
0500:                        if (txt.equals("import"))
0501:                            importFound = true;
0502:                    } catch (Exception e) {
0503:                        e.printStackTrace();
0504:                    }
0505:                }
0506:
0507:                if (offset > 13) {
0508:                    try {
0509:                        String txt = editor.getDocument().getText(offset - 13,
0510:                                13);
0511:                        //System.out.println(""+txt);
0512:                        if (txt.equals("import static"))
0513:                            importFound = true;
0514:                    } catch (Exception e) {
0515:                        e.printStackTrace();
0516:                    }
0517:                }
0518:
0519:                if (importFound) {
0520:                    // abort if in comment of in litteral
0521:                    if (isInStringOrComment(offset)) {
0522:                        replacement = " ";
0523:                        fb.replace(offset, length, replacement, attrs);
0524:                        return replacement;
0525:                    }
0526:
0527:                }
0528:
0529:                if (!importFound) {
0530:                    try {
0531:                        // simple replace.
0532:                        replacement = " ";
0533:                        fb.replace(offset, length, replacement, attrs);
0534:                    } catch (Exception e) {
0535:                        e.printStackTrace();
0536:                    }
0537:                } else {
0538:                    Rectangle posPt; // = new Rectangle(0,0,10,10);
0539:                    try {
0540:                        posPt = editor.getTextPane().modelToView(offset);
0541:                        Point pts = editor.getTextPane().getLocationOnScreen();
0542:                        ImportCompletionDialog acd = new ImportCompletionDialog(
0543:                                false, MainEditorFrame.instance, (int) (pts
0544:                                        .getX() + posPt.getX()), (int) (pts
0545:                                        .getY()
0546:                                        + posPt.getY() + editor.getTextPane()
0547:                                        .getFont().getSize()), editor
0548:                                        .getTextPane().getDocument(), offset,
0549:                                false, null);
0550:
0551:                        replacement = "";
0552:                        if (!acd.getWasCancelled()) {
0553:                            replacement = " " + acd.getSelectionAndClear();
0554:                        } else {
0555:                            acd.clear();
0556:                            replacement = " ";
0557:                        }
0558:
0559:                        fb.replace(offset, length, replacement, attrs);
0560:
0561:                    } catch (Exception e) {
0562:                        e.printStackTrace();
0563:                    }
0564:                }
0565:                return replacement;
0566:            }
0567:
0568:            /** Also used from the editor.
0569:             */
0570:            public FileItem locateType(FileItem editedSource,
0571:                    String javaNameToLocate, boolean _allowLazyInexactSearch) {
0572:                return locateTypeUsingImports(editedSource, javaNameToLocate,
0573:                        _allowLazyInexactSearch);
0574:            }
0575:
0576:            /** null if no sst available
0577:             */
0578:            public List<FileItem> locateEventualMissingImport(
0579:                    FileItem editedSource, String javaNameToLocate) {
0580:                if (editedSource.getParserResultIfAlreadyMade() != null) {
0581:                    if (editedSource.getParserResultIfAlreadyMade().compilationUnit != null) {
0582:                        return locateMissingImport(editedSource
0583:                                .getParserResultIfAlreadyMade(),
0584:                                javaNameToLocate, editedSource.getPackageName());
0585:                    }
0586:                }
0587:
0588:                // OLD
0589:                @SuppressWarnings("deprecation")
0590:                SimplifiedSyntaxTree2 sst = editedSource
0591:                        .getSimplifiedSyntaxTreeIfAlreadyMade();
0592:                if (sst == null)
0593:                    return null;
0594:                ParserTreeNode importsNode = sst.importsNode;
0595:                return locateMissingImport(importsNode, javaNameToLocate,
0596:                        editedSource.getPackageName());
0597:            }
0598:
0599:            /** Suitable for a type in the short form in the source code (from which the import node comes)
0600:             *  or an absolute type name.
0601:             */
0602:            private FileItem locateTypeUsingImports(final FileItem source,
0603:                    final String javaNameToLocate,
0604:                    final boolean _allowLazyInexactSearch) {
0605:                if (javaNameToLocate.indexOf('$') > 0) {
0606:                    // TODO: internal class encountered !!
0607:                }
0608:
0609:                // use first the imports (ordered) to search for the name, first try absolute matching !
0610:                FileItem it = TypeLocator.locateUsingImports(source,
0611:                        javaNameToLocate);
0612:                if (it != null)
0613:                    return it;
0614:
0615:                // lazy search
0616:                if (_allowLazyInexactSearch) {
0617:                    it = TypeLocator.searchTypeForName(javaNameToLocate, true,
0618:                            true);
0619:                }
0620:
0621:                return it;
0622:            }
0623:
0624:            /* Suitable for a type in the short form in the source code (from which the import node comes)
0625:             *  or an absolute type name.
0626:             *
0627:            private FileItem locateTypeUsingImports(final ParserResult pr, String javaNameToLocate, String sourcePackage, boolean _allowLazyInexactSearch)
0628:            {
0629:               if(javaNameToLocate.indexOf('$')>0)
0630:               {
0631:                  // TODO: internal class encountered !!
0632:               }
0633:
0634:               FileItem it = null;
0635:               if(pr!=null && pr.compilationUnit!=null)
0636:               {
0637:                 // use first the imports (ordered) to search for the name, first try absolute matching !
0638:                 it = TypeLocator.locateUsingImports(pr, javaNameToLocate, sourcePackage);
0639:                 if(it!=null) return it;
0640:               }
0641:
0642:               // lazy search
0643:               if(_allowLazyInexactSearch)
0644:               {
0645:                 it = TypeLocator.searchTypeForName(javaNameToLocate, true, true);
0646:               }
0647:
0648:               return it;
0649:            }*/
0650:
0651:            /** null if no importsNode given
0652:             */
0653:            @Deprecated
0654:            private List<FileItem> locateMissingImport(
0655:                    ParserTreeNode importsNode, String javaNameToLocate,
0656:                    String sourcePackage) {
0657:                if (importsNode != null) {
0658:                    // use first the imports (ordered) to search for the name, first try absolute matching !
0659:                    return TypeLocator.locateMissingImport(importsNode,
0660:                            javaNameToLocate, sourcePackage);
0661:                }
0662:
0663:                return null;
0664:            }
0665:
0666:            /** null if no importsNode given
0667:             */
0668:            private List<FileItem> locateMissingImport(final ParserResult pr,
0669:                    final String javaNameToLocate, final String sourcePackage) {
0670:                if (pr != null && pr.compilationUnit != null) {
0671:                    // use first the imports (ordered) to search for the name, first try absolute matching !
0672:                    return TypeLocator.locateMissingImport(pr,
0673:                            javaNameToLocate, sourcePackage);
0674:                }
0675:
0676:                return null;
0677:            }
0678:
0679:            private boolean isInStringOrComment(int offset) {
0680:                final SimpleDocument doc = editor.getDocument();
0681:                try {
0682:                    String txtUpto = doc.getText(0, offset);
0683:                    if (SyntaxUtils.isInString(txtUpto, offset))
0684:                        return true;
0685:
0686:                    if (SyntaxUtils.isInComment(txtUpto, offset))
0687:                        return true;
0688:                } catch (Exception e) {
0689:                }
0690:
0691:                return false;
0692:            }
0693:
0694:            /** For the completion based on the reflection, the full class name is all what we need.
0695:             *
0696:             * @return null if not resolved or primitive type.
0697:             */
0698:            public String resolveClassName(final FileItem editedSource,
0699:                    final IDChainElement ide, final SingleClassLoader scl) {
0700:                if (ide.getArrayDepth() > 0) {
0701:                    // array completion => ".length" and object
0702:                    return "java.lang.Object";
0703:                } else if (ide.isPrimitiveType) {
0704:                    // no completions for "int", "double", ...
0705:                    return null;
0706:                }
0707:
0708:                // try first with the class (most accurate way)
0709:                if (ide.reflectedObject != null) {
0710:                    if (ide.reflectedObject instanceof  Class) {
0711:                        return ((Class) ide.reflectedObject).getName();
0712:                    } else {
0713:                        System.out.println("UNKN::"
0714:                                + ide.reflectedObject.getClass());
0715:                    }
0716:                }
0717:
0718:                FileItem resolvedType = ide.resolvedType_.fitem;
0719:                if (resolvedType != null) {
0720:                    return resolvedType.getJavaName();
0721:                }
0722:
0723:                // Special case for inner classes: if a $ is present, it is resolved !!
0724:                String typeName = ide.getTypeMaybeResolved();
0725:
0726:                if (typeName != null && typeName.indexOf('$') > 0) {
0727:                    return typeName;
0728:                }
0729:
0730:                MainEditorFrame.debugOut("Try to locate type " + typeName);
0731:
0732:                if (typeName != null) {
0733:                    resolvedType = locateTypeUsingImports(editedSource,
0734:                            typeName, allowLazyInexactSearch);
0735:                    if (resolvedType != null) {
0736:                        return resolvedType.getJavaName();
0737:                    } else {
0738:                        //MainEditorFrame.debugOut("CM::no type found for class "+typeName);
0739:                        if (ide.reflectedObject == null) {
0740:                            //System.out.println("ide.reflectedObject="+ide.reflectedObject);
0741:                            // [Feb2008]
0742:                            return typeName;
0743:                        }
0744:                    }
0745:                }
0746:
0747:                return null;
0748:            }
0749:
0750:            /** "." completion, complete class names (static), constructors (if new preceeds) and field and methods names.
0751:             *   One of the most *tuned* methods to give nice results. Don't shows local variables, because adter a "dot" they can't come.
0752:             *
0753:             *    javax.swing.JFrame#
0754:             *    a#
0755:             *    a.b.c#
0756:             *    "abc"#
0757:             *    new Point2D#
0758:             *    new Throwable().printStackTrace();
0759:             *    a[3][5]#
0760:             *
0761:             * @return the replacement that was selected
0762:             */
0763:            public String pointPressed(final FileItem editedSource,
0764:                    final DocumentFilter.FilterBypass fb, final int offset,
0765:                    final int length, final AttributeSet attrs)
0766:                    throws Exception {
0767:
0768:                final SimpleDocument doc = editor.getDocument();
0769:
0770:                // 0) check if dot pressed in comment or litteral (don't complete if so)
0771:                //
0772:
0773:                if (isInStringOrComment(offset)) {
0774:                    try {
0775:                        fb.replace(offset, length, ".", attrs);
0776:                        return ".";
0777:                    } catch (Exception e) {
0778:                        e.printStackTrace();
0779:                    }
0780:                }
0781:
0782:                final SingleClassLoader scl = SingleClassLoader
0783:                        .createSingleClassLoader();
0784:                // detect the identifier before offset
0785:                // this is trimmed and without spaces. ex: System.out.println
0786:                //   or  a().re[][] , with empty parenthesis and brackets...
0787:                final ParsedID pid = SyntaxUtils.getJavaIdentifierBefore(doc,
0788:                        offset, null);
0789:                final IDChain resolver = new IDChain(pid, editedSource, doc,
0790:                        offset, ".", scl);
0791:
0792:                String id = pid.identifierChain;
0793:                MainEditorFrame.debugOut("\n=== ID resolver: " + resolver
0794:                        + "\n");
0795:
0796:                String repl = ".";
0797:
0798:                // this is what we need,  "java.lang.String" is resolved, "String" is not.
0799:                // we can reach "more" with a string as with a FileItem when
0800:                String resolvedClassName = null;
0801:
0802:                boolean staticOnly = false;
0803:                boolean includePrivate = false;
0804:                boolean includeProtected = false;
0805:                boolean includePackageScope = false;
0806:                boolean constructorMode = (pid != null && pid.precedingItem
0807:                        .equals("new"));
0808:
0809:                String typeParameters = null;
0810:
0811:                // 2) exact parser based type search
0812:                boolean isArrayCompletion = false;
0813:                final IDChainElement ide;
0814:                if (resolver != null && resolver.isValid()
0815:                        && resolver.getLastChainComponent() != null) {
0816:                    // we have a valid chain => locate the type !
0817:
0818:                    ide = resolver.getLastChainComponent();
0819:                    typeParameters = ide.getTypeParameters(); //    for example String in List<String>
0820:
0821:                    // we can be more precise than above
0822:                    if (ide.getKind() == ElementKind.Constructor) {
0823:                        // YES ! seems strange, but it really is so ! as in new "Throwable()." after the dot, we have methods and fields !
0824:                        constructorMode = false;
0825:                    } else if (ide.getKind() == ElementKind.Class) {
0826:                        staticOnly = !ide.isClassCast;
0827:                    }
0828:
0829:                    if (ide.getArrayDepth() > 0) {
0830:                        // array completion => ".length" and object
0831:                        isArrayCompletion = true;
0832:                        resolvedClassName = "java.lang.Object";
0833:                    } else if (ide.isPrimitiveType) {
0834:                        // no completions for "int", "double", ...
0835:                        fb.replace(offset, length, ".", attrs);
0836:                        return ".";
0837:                    }
0838:
0839:                    // [Feb2008]: put the code in a method, to share with CtrlSpace action
0840:                    resolvedClassName = resolveClassName(editedSource, ide, scl);
0841:
0842:                    FileItem resolvedType = ide.resolvedType_.fitem;
0843:
0844:                    String fullIDName = resolver.pid.identifierChain;
0845:                    if (fullIDName.endsWith("this")
0846:                            || fullIDName.endsWith("super")) {
0847:                        includePrivate = true;
0848:                        includeProtected = true;
0849:                        includePackageScope = true;
0850:                    }
0851:                } else {
0852:                    ide = null;
0853:                }
0854:
0855:                String specialCompletionPrepend = null;
0856:                int rewind = 0;
0857:                if (resolvedClassName != null) {
0858:                    // may be null ! (for inner classes)
0859:                    FileItem fileItemForClass = null;
0860:                    Class resolvedClass = null;
0861:                    String resolvedPackageName = null;
0862:
0863:                    if (ide != null
0864:                            && ide.getKind() == ElementKind.PackageNameFragment) {
0865:                        fileItemForClass = ide.resolvedType_.fitem;
0866:                    } else {
0867:                        if (ide != null && ide.resolvedType_.isResolved()) {
0868:                            fileItemForClass = ide.resolvedType_.fitem;
0869:                        } else {
0870:                            fileItemForClass = TypeLocator
0871:                                    .locateQuick(resolvedClassName);
0872:                        }
0873:
0874:                        try {
0875:                            resolvedClass = scl.loadClass(resolvedClassName);
0876:                        } catch (Exception e) {
0877:                            e.printStackTrace();
0878:                        } catch (Error e) {
0879:                            e.printStackTrace();
0880:                        }
0881:
0882:                        if (fileItemForClass != null) {
0883:                            resolvedPackageName = fileItemForClass
0884:                                    .getPackageName();
0885:                        } else if (resolvedClass != null) {
0886:                            resolvedPackageName = ClassUtils
0887:                                    .getPackageName(resolvedClass);
0888:                            if (resolvedPackageName == null) {
0889:                                System.out.println("Null package name for "
0890:                                        + resolvedClass);
0891:                            }
0892:                        }
0893:                    }
0894:
0895:                    // todo: look in the extends and implements !!!
0896:                    if (!includePrivate) {
0897:                        includePrivate = resolvedClassName.equals(editedSource
0898:                                .getJavaName());
0899:                    }
0900:                    if (!includeProtected) {
0901:                        includeProtected = includePrivate; // TODO:
0902:                    }
0903:                    if (!includePackageScope) {
0904:                        if (resolvedPackageName != null) {
0905:                            includePackageScope = resolvedPackageName
0906:                                    .equals(editedSource.getPackageName());
0907:                        } else {
0908:                            includePackageScope = true;
0909:                        }
0910:                    }
0911:
0912:                    final String ftypeParameters = typeParameters;
0913:
0914:                    Rectangle posPt = editor.getTextPane().modelToView(offset);
0915:                    Point pts = editor.getTextPane().getLocationOnScreen();
0916:
0917:                    //TODO: look at class name and edited class name to decide if package scope enabled...
0918:                    boolean onlyPublic = false;
0919:                    if (ide != null) {
0920:                        if (ide.resolvedType_.isResolved()) {
0921:                            if (!SyntaxUtils.getPackageName(
0922:                                    ide.resolvedType_.getJavaName()).equals(
0923:                                    SyntaxUtils.getPackageName(editedSource
0924:                                            .getJavaName()))) {
0925:                                onlyPublic = true;
0926:                                //System.out.println("Only public because "+ide.resolvedType_.getJavaName()+" != "+editedSource.getJavaName());
0927:                                //snow.utils.gui.FileChooserFilter$SearchHit != snow.utils.gui.FileChooserFilter
0928:
0929:                            }
0930:                        }
0931:                    }
0932:
0933:                    final AttributeCompletionDialog acd = new AttributeCompletionDialog(
0934:                            MainEditorFrame.instance, (int) (pts.getX() + posPt
0935:                                    .getX()),
0936:                            (int) (pts.getY() + posPt.getY() + editor
0937:                                    .getTextPane().getFont().getSize()), doc,
0938:                            offset, isArrayCompletion ? "Array completion"
0939:                                    : resolvedClassName
0940:                                            + (ftypeParameters != null ? " <"
0941:                                                    + ftypeParameters + ">"
0942:                                                    : ""), //TODO add "extends XXX" if so
0943:                            onlyPublic);
0944:
0945:                    final FileItem ffoundType = fileItemForClass;
0946:                    final String fresolvedClassName = resolvedClassName;
0947:                    final boolean fincludePrivate = includePrivate;
0948:                    final boolean fincludeProtected = includeProtected;
0949:                    final boolean fincludePackageScope = includePackageScope;
0950:                    final boolean fstaticOnly = staticOnly;
0951:                    final boolean fisArrayCompletion = isArrayCompletion;
0952:                    final boolean fconstructorMode = constructorMode;
0953:
0954:                    acd.addFactoryBarForPointCompletion();
0955:
0956:                    Thread t = new Thread() {
0957:                        public void run() {
0958:                            List<AttrCompletionItem> av = null;
0959:
0960:                            if (fisArrayCompletion) {
0961:                                // [April2007]
0962:                                av = ClassSyntaxManager.getAttributes(scl,
0963:                                        "java.lang.Object", "", false, false,
0964:                                        false, false);
0965:                                av.add(0, AttrCompletionItem.arrayLengthItem());
0966:
0967:                            } else if (ffoundType != null
0968:                                    && ffoundType.isDirectory()) {
0969:                                // package completion
0970:                                final String packageName = ffoundType
0971:                                        .getPackageName();
0972:                                // Also find other jars starting with that name...  "javax" may be present in several jars...
0973:                                // look in all libs !! [March2007]
0974:                                List<FileItem> packs = TypeLocator
0975:                                        .locateAllPackages(packageName);
0976:
0977:                                av = new ArrayList<AttrCompletionItem>();
0978:
0979:                                for (FileItem pi : packs) {
0980:                                    for (int i = 0; i < pi.getChildCount(); i++) {
0981:                                        FileItem fi = (FileItem) pi
0982:                                                .getChildAt(i);
0983:                                        if (fi.isDirectory()) {
0984:                                            av
0985:                                                    .add(AttrCompletionItem
0986:                                                            .createNameCompletionForPackage(fi));
0987:                                        } else {
0988:                                            av
0989:                                                    .add(AttrCompletionItem
0990:                                                            .createNameCompletionForClass(fi));
0991:                                        }
0992:                                        // TODO: show only 2 columns in the completion table.
0993:                                    }
0994:                                }
0995:
0996:                                EventQueue.invokeLater(new Runnable() {
0997:                                    public void run() {
0998:                                        acd.setTitle("Package " + packageName
0999:                                                + " completion");
1000:                                    }
1001:                                });
1002:
1003:                            } else if (fconstructorMode) {
1004:                                av = ClassSyntaxManager
1005:                                        .getCompletionForConstructors(scl,
1006:                                                fresolvedClassName,
1007:                                                ftypeParameters,
1008:                                                fincludePrivate,
1009:                                                fincludeProtected,
1010:                                                fincludePackageScope,
1011:                                                fstaticOnly);
1012:                            } else {
1013:                                av = ClassSyntaxManager.getAttributes(scl,
1014:                                        fresolvedClassName, ftypeParameters,
1015:                                        fincludePrivate, fincludeProtected,
1016:                                        fincludePackageScope, fstaticOnly);
1017:                            }
1018:
1019:                            if (av != null && av.size() > 0) {
1020:                                acd.setCompletionItems(av);
1021:                            } else {
1022:                                EventQueue.invokeLater(new Runnable() {
1023:                                    public void run() {
1024:                                        System.out.println("cancel dot dialog");
1025:                                        acd.cancelDialog();
1026:                                    }
1027:                                });
1028:                            }
1029:                        }
1030:                    };
1031:                    t.setName("AttributesCompletion:names");
1032:                    t.setPriority(Thread.NORM_PRIORITY - 1);
1033:                    t.start();
1034:
1035:                    acd.setVisible(true); // MODAL !
1036:
1037:                    repl = "." + acd.getSelectionAndClear();
1038:                    specialCompletionPrepend = acd
1039:                            .getSpecialCompletionPrepend();
1040:                    rewind = acd.caretRewind;
1041:                } else {
1042:                    MainEditorFrame
1043:                            .debugOut("no type for " + resolvedClassName);
1044:                }
1045:
1046:                fb.replace(offset, length, repl, attrs);
1047:
1048:                if (specialCompletionPrepend != null) {
1049:                    // before offset
1050:                    //TODO: search the position of the preceding space.(before identifier)
1051:                    //DocumentUtils.
1052:
1053:                    int posStartID = offset - 1;
1054:                    if (pid != null) {
1055:                        posStartID = pid.startPositionInDocument;
1056:                    }
1057:
1058:                    //System.out.println("Insert "+specialCompletionPrepend+" at "+posStartID);
1059:
1060:                    fb.replace(posStartID, 0, specialCompletionPrepend, attrs);
1061:
1062:                    //SPECIAL CASE!! manage ourselves
1063:                    editor.getCodeStyler().userInsertOccured(offset,
1064:                            repl.length() - length);
1065:                    return null;
1066:                } else {
1067:                    if (rewind != 0) {
1068:                        editor.getTextPane().setCaretPosition(
1069:                                editor.getTextPane().getCaretPosition()
1070:                                        - rewind);
1071:                    }
1072:                }
1073:
1074:                return repl;
1075:            }
1076:
1077:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.