Source Code Cross Referenced for CsmSyntaxSupport.java in  » IDE-Netbeans » cnd » org » netbeans » modules » cnd » completion » cplusplus » ext » 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 Netbeans » cnd » org.netbeans.modules.cnd.completion.cplusplus.ext 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
0003:         *
0004:         * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
0005:         *
0006:         * The contents of this file are subject to the terms of either the GNU
0007:         * General Public License Version 2 only ("GPL") or the Common
0008:         * Development and Distribution License("CDDL") (collectively, the
0009:         * "License"). You may not use this file except in compliance with the
0010:         * License. You can obtain a copy of the License at
0011:         * http://www.netbeans.org/cddl-gplv2.html
0012:         * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
0013:         * specific language governing permissions and limitations under the
0014:         * License.  When distributing the software, include this License Header
0015:         * Notice in each file and include the License file at
0016:         * nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
0017:         * particular file as subject to the "Classpath" exception as provided
0018:         * by Sun in the GPL Version 2 section of the License file that
0019:         * accompanied this code. If applicable, add the following below the
0020:         * License Header, with the fields enclosed by brackets [] replaced by
0021:         * your own identifying information:
0022:         * "Portions Copyrighted [year] [name of copyright owner]"
0023:         *
0024:         * Contributor(s):
0025:         *
0026:         * The Original Software is NetBeans. The Initial Developer of the Original
0027:         * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
0028:         * Microsystems, Inc. All Rights Reserved.
0029:         *
0030:         * If you wish your version of this file to be governed by only the CDDL
0031:         * or only the GPL Version 2, indicate your decision by adding
0032:         * "[Contributor] elects to include this software in this distribution
0033:         * under the [CDDL or GPL Version 2] license." If you do not indicate a
0034:         * single choice of license, a recipient has the option to distribute
0035:         * your version of this file under either the CDDL, the GPL Version 2 or
0036:         * to extend the choice of license to its licensees as provided above.
0037:         * However, if you add GPL Version 2 code and therefore, elected the GPL
0038:         * Version 2 license, then the option applies only if the new code is
0039:         * made subject to such option by the copyright holder.
0040:         */
0041:
0042:        package org.netbeans.modules.cnd.completion.cplusplus.ext;
0043:
0044:        import org.netbeans.modules.cnd.api.model.CsmClass;
0045:        import org.netbeans.modules.cnd.api.model.CsmClassifier;
0046:        import org.netbeans.modules.cnd.api.model.CsmParameter;
0047:        import org.netbeans.modules.cnd.api.model.CsmType;
0048:        import org.netbeans.modules.cnd.api.model.CsmVariable;
0049:        import org.netbeans.modules.cnd.api.model.util.CsmKindUtilities;
0050:        import java.util.ArrayList;
0051:        import java.util.List;
0052:        import java.util.Map;
0053:        import java.util.HashMap;
0054:        import java.util.Iterator;
0055:        import javax.swing.text.BadLocationException;
0056:        import javax.swing.event.DocumentEvent;
0057:        import javax.swing.text.JTextComponent;
0058:        import org.netbeans.editor.BaseDocument;
0059:        import org.netbeans.editor.TokenItem;
0060:        import org.netbeans.editor.Utilities;
0061:        import org.netbeans.editor.TextBatchProcessor;
0062:        import org.netbeans.editor.FinderFactory;
0063:        import org.netbeans.editor.Analyzer;
0064:        import org.netbeans.editor.StringMap;
0065:        import org.netbeans.editor.TokenID;
0066:        import org.netbeans.editor.TokenContextPath;
0067:        import org.netbeans.editor.ext.ExtSyntaxSupport.DeclarationTokenProcessor;
0068:        import org.netbeans.editor.ext.ExtSyntaxSupport.VariableMapTokenProcessor;
0069:        import org.netbeans.modules.cnd.api.model.CsmFunction;
0070:        import org.netbeans.modules.cnd.api.model.CsmOffsetableDeclaration;
0071:        import org.netbeans.modules.cnd.completion.csm.CompletionUtilities;
0072:        import org.netbeans.modules.cnd.editor.cplusplus.CCTokenContext;
0073:        import org.netbeans.modules.cnd.editor.spi.cplusplus.CCSyntaxSupport;
0074:
0075:        /**
0076:         * Support methods for csm based syntax analyzes
0077:         *
0078:         * @author Vladimir Voskresensky
0079:         * @version 1.00
0080:         * implemented after JavaSyntaxSupport
0081:         */
0082:
0083:        abstract public class CsmSyntaxSupport extends CCSyntaxSupport {
0084:
0085:            // Internal C++ declaration token processor states
0086:            static final int INIT = 0;
0087:            static final int AFTER_TYPE = 1;
0088:            static final int AFTER_VARIABLE = 2;
0089:            static final int AFTER_COMMA = 3;
0090:            static final int AFTER_DOT = 4;
0091:            static final int AFTER_TYPE_LSB = 5;
0092:            static final int AFTER_MATCHING_VARIABLE_LSB = 6;
0093:            static final int AFTER_MATCHING_VARIABLE = 7;
0094:            static final int AFTER_EQUAL = 8; // in decl after "var ="
0095:            static final int AFTER_ARROW = 9;
0096:            static final int AFTER_SCOPE = 10;
0097:
0098:            private static final TokenID[] COMMENT_TOKENS = new TokenID[] {
0099:                    CCTokenContext.LINE_COMMENT, CCTokenContext.BLOCK_COMMENT };
0100:
0101:            private static final TokenID[] BRACKET_SKIP_TOKENS = new TokenID[] {
0102:                    CCTokenContext.LINE_COMMENT, CCTokenContext.BLOCK_COMMENT,
0103:                    CCTokenContext.CHAR_LITERAL, CCTokenContext.STRING_LITERAL };
0104:
0105:            // tokens valid for include-completion provider
0106:            private static final TokenID[] INCLUDE_COMPLETION_TOKENS = new TokenID[] {
0107:                    CCTokenContext.USR_INCLUDE, CCTokenContext.SYS_INCLUDE,
0108:                    CCTokenContext.INCOMPLETE_SYS_INCLUDE,
0109:                    CCTokenContext.INCOMPLETE_USR_INCLUDE };
0110:            // tokens invalid for general completion provider: skip tokens + include tokens
0111:            private static final TokenID[] COMPLETION_SKIP_TOKENS;
0112:            static {
0113:                int brLen = BRACKET_SKIP_TOKENS.length;
0114:                int incLen = INCLUDE_COMPLETION_TOKENS.length;
0115:                COMPLETION_SKIP_TOKENS = new TokenID[brLen + incLen];
0116:                System.arraycopy(BRACKET_SKIP_TOKENS, 0,
0117:                        COMPLETION_SKIP_TOKENS, 0, brLen);
0118:                System.arraycopy(INCLUDE_COMPLETION_TOKENS, 0,
0119:                        COMPLETION_SKIP_TOKENS, brLen, incLen);
0120:            }
0121:
0122:            private static final char[] COMMAND_SEPARATOR_CHARS = new char[] {
0123:                    ';', '{', '}' };
0124:
0125:            private CsmIncludeProcessor javaImport;
0126:
0127:            /** Whether java 1.5 constructs are recognized. */
0128:            private boolean java15;
0129:
0130:            public CsmSyntaxSupport(BaseDocument doc) {
0131:                super (doc);
0132:
0133:                tokenNumericIDsValid = true;
0134:            }
0135:
0136:            abstract protected CsmFinder getFinder();
0137:
0138:            protected CsmIncludeProcessor createIncludeProc() {
0139:                return new CsmIncludeProcessor(this );
0140:            }
0141:
0142:            @Override
0143:            protected void documentModified(DocumentEvent evt) {
0144:                super .documentModified(evt);
0145:                classFieldMaps.clear();
0146:                fileVariableMaps.clear();
0147:                if (javaImport != null) {
0148:                    javaImport.documentModifiedAtPosition(evt.getOffset(),
0149:                            getDocument());
0150:                }
0151:            }
0152:
0153:            protected void setJava15(boolean java15) {
0154:                this .java15 = java15;
0155:            }
0156:
0157:            @Override
0158:            public TokenID[] getCommentTokens() {
0159:                return COMMENT_TOKENS;
0160:            }
0161:
0162:            @Override
0163:            public TokenID[] getBracketSkipTokens() {
0164:                return BRACKET_SKIP_TOKENS;
0165:            }
0166:
0167:            /** Return the position of the last command separator before
0168:             * the given position.
0169:             */
0170:            @Override
0171:            public int getLastCommandSeparator(final int pos)
0172:                    throws BadLocationException {
0173:                if (pos == 0)
0174:                    return 0;
0175:                final int posLine = Utilities.getLineOffset(getDocument(), pos);
0176:                TextBatchProcessor tbp = new TextBatchProcessor() {
0177:                    public int processTextBatch(BaseDocument doc, int startPos,
0178:                            int endPos, boolean lastBatch) {
0179:                        try {
0180:                            int[] blks = getCommentBlocks(endPos, startPos);
0181:                            FinderFactory.CharArrayBwdFinder cmdFinder = new FinderFactory.CharArrayBwdFinder(
0182:                                    COMMAND_SEPARATOR_CHARS);
0183:                            int lastSeparatorOffset = findOutsideBlocks(
0184:                                    cmdFinder, startPos, endPos, blks);
0185:                            if (lastSeparatorOffset < 1)
0186:                                return lastSeparatorOffset;
0187:                            TokenID separatorID = getTokenID(lastSeparatorOffset);
0188:                            if (separatorID.getNumericID() == CCTokenContext.RBRACE_ID) {
0189:                                int matchingBrkPos[] = findMatchingBlock(
0190:                                        lastSeparatorOffset, true);
0191:                                if (matchingBrkPos != null) {
0192:                                    int prev = Utilities.getFirstNonWhiteBwd(
0193:                                            getDocument(), matchingBrkPos[0]);
0194:                                    if (prev > -1
0195:                                            && getTokenID(prev).getNumericID() == CCTokenContext.RBRACKET_ID) {
0196:                                        return getLastCommandSeparator(prev);
0197:                                    }
0198:                                }
0199:                            } else if (separatorID.getCategory() == CCTokenContext.CPP) {
0200:                                // found preprocessor directive, skip till the end of it
0201:                                int separatorLine = Utilities.getLineOffset(
0202:                                        getDocument(), lastSeparatorOffset);
0203:                                assert (separatorLine <= posLine);
0204:                                if (separatorLine != posLine) {
0205:                                    lastSeparatorOffset = Utilities.getRowEnd(
0206:                                            getDocument(), lastSeparatorOffset);
0207:                                }
0208:                            }
0209:                            if (separatorID.getNumericID() != CCTokenContext.LBRACE_ID
0210:                                    && separatorID.getNumericID() != CCTokenContext.RBRACE_ID
0211:                                    && separatorID.getNumericID() != CCTokenContext.SEMICOLON_ID
0212:                                    && separatorID.getCategory() != CCTokenContext.CPP) {
0213:                                lastSeparatorOffset = processTextBatch(doc,
0214:                                        lastSeparatorOffset, 0, lastBatch);
0215:                            }
0216:                            return lastSeparatorOffset;
0217:                        } catch (BadLocationException e) {
0218:                            e.printStackTrace();
0219:                            return -1;
0220:                        }
0221:                    }
0222:                };
0223:                int lastPos = getDocument().processText(tbp, pos, 0);
0224:
0225:                //ensure we return last command separator from last 
0226:                //block of C++ tokens from <startPos;endPos> offset interval
0227:                //AFAIK this is currently needed only for JSP code completion
0228:                TokenItem item = getTokenChain(pos - 1, pos);
0229:                //go back throught the token chain and try to find last C++ token
0230:                while (item != null) {
0231:                    int tokenOffset = item.getOffset();
0232:                    if (lastPos != -1 && tokenOffset < lastPos)
0233:                        break; //stop backtracking if we met the lastPos
0234:                    //test token type
0235:                    if (!item.getTokenContextPath().contains(
0236:                            CCTokenContext.contextPath)) {
0237:                        //return offset of last C++ token - this token isn't already a C++ token so return offset of next token
0238:                        lastPos = item.getNext() != null ? item.getNext()
0239:                                .getOffset() : item.getOffset()
0240:                                + item.getImage().length();
0241:                        break;
0242:                    }
0243:                    item = item.getPrevious();
0244:                }
0245:
0246:                return lastPos;
0247:            }
0248:
0249:            /** Get the class from name. The import sections are consulted to find
0250:             * the proper package for the name. If the search in import sections fails
0251:             * the method can ask the finder to search just by the given name.
0252:             * @param className name to resolve. It can be either the full name
0253:             *   or just the name without the package.
0254:             * @param searchByName if true and the resolving through the import sections fails
0255:             *   the finder is asked to find the class just by the given name
0256:             */
0257:            public CsmClass getClassFromName(String className,
0258:                    boolean searchByName) {
0259:                refreshJavaImport();
0260:                // XXX handle primitive type
0261:                CsmClass ret = null;
0262:                //        CsmClass ret = JavaCompletion.getPrimitiveClass(className);
0263:                //        if (ret == null) {
0264:                //            
0265:                //            ret = getIncludeProc().getClassifier(className);
0266:                //        }
0267:                if (ret == null && searchByName) {
0268:                    if (isUnknownInclude(className))
0269:                        return null;
0270:                    List clsList = getFinder().findClasses(null, className,
0271:                            true, false);
0272:                    if (clsList != null && clsList.size() > 0) {
0273:                        if (clsList.size() > 0
0274:                                && (clsList.get(0) instanceof  CsmClass)) { // more matching classes
0275:                            ret = (CsmClass) clsList.get(0); // get the first one
0276:                        }
0277:                    }
0278:
0279:                }
0280:                return ret;
0281:            }
0282:
0283:            public synchronized CsmIncludeProcessor getIncludeProc() {
0284:                if (javaImport == null) {
0285:                    javaImport = createIncludeProc();
0286:                }
0287:                javaImport.update(getDocument());
0288:                return javaImport;
0289:            }
0290:
0291:            protected boolean isUnknownInclude(String className) {
0292:                return getIncludeProc().isUnknownImport(className);
0293:            }
0294:
0295:            /** Returns all imports that aren't in Code Completion DB yet */
0296:            protected List getUnknownIncludes() {
0297:                return getIncludeProc().getUnknownImports();
0298:            }
0299:
0300:            // VK: never used - commented this out
0301:            //    /** Returns true if the given class is in the import statement directly or
0302:            //     *  indirectly (package.name.*) */    
0303:            //    public boolean isIcluded(CsmClass cls){
0304:            //        return getIncludeProc().isIncluded(cls);
0305:            //    }
0306:
0307:            public void refreshJavaImport() {
0308:                if (javaImport != null) {
0309:                    javaImport.update(getDocument());
0310:                }
0311:            }
0312:
0313:            protected void refreshClassInfo() {
0314:            }
0315:
0316:            protected List getImportedInnerClasses() {
0317:                refreshJavaImport();
0318:                return getIncludeProc().getInnerClasses();
0319:            }
0320:
0321:            /** Get the class that belongs to the given position */
0322:            public CsmClass getClass(int pos) {
0323:                return CompletionUtilities.findClassOnPosition(getDocument(),
0324:                        pos);
0325:            }
0326:
0327:            /** Get the class or function definition that belongs to the given position */
0328:            public CsmOffsetableDeclaration getDefinition(int pos) {
0329:                return CompletionUtilities.findFunDefinitionOrClassOnPosition(
0330:                        getDocument(), pos);
0331:            }
0332:
0333:            public boolean isStaticBlock(int pos) {
0334:                return false;
0335:            }
0336:
0337:            public boolean isAnnotation(int pos) {
0338:                try {
0339:                    BaseDocument document = getDocument();
0340:                    int off = Utilities.getFirstNonWhiteBwd(document, pos);
0341:                    char ch = '*'; // NOI18N
0342:                    while (off > -1
0343:                            && (ch = document.getChars(off, 1)[0]) == '.') { // NOI18N
0344:                        off = Utilities.getFirstNonWhiteBwd(document, off);
0345:                        if (off > -1)
0346:                            off = Utilities.getPreviousWord(document, off);
0347:                        if (off > -1)
0348:                            off = Utilities.getFirstNonWhiteBwd(document, off);
0349:                    }
0350:                    if (off > -1 && ch == '@') // NOI18N
0351:                        return true;
0352:                } catch (BadLocationException e) {
0353:                }
0354:                return false;
0355:            }
0356:
0357:            @Override
0358:            public int[] getFunctionBlock(int[] identifierBlock)
0359:                    throws BadLocationException {
0360:                int[] retValue = super .getFunctionBlock(identifierBlock);
0361:                if (!isAnnotation(identifierBlock[0]))
0362:                    return retValue;
0363:                return null;
0364:            }
0365:
0366:            @Override
0367:            protected DeclarationTokenProcessor createDeclarationTokenProcessor(
0368:                    String varName, int startPos, int endPos) {
0369:                return java15 ? (DeclarationTokenProcessor) new CsmDeclarationProcessor(
0370:                        this , varName)
0371:                        : (DeclarationTokenProcessor) new CsmDeclarationTokenProcessor(
0372:                                this , varName);
0373:            }
0374:
0375:            @Override
0376:            protected VariableMapTokenProcessor createVariableMapTokenProcessor(
0377:                    int startPos, int endPos) {
0378:                return java15 ? (VariableMapTokenProcessor) new CsmDeclarationProcessor(
0379:                        this , null)
0380:                        : (VariableMapTokenProcessor) new CsmDeclarationTokenProcessor(
0381:                                this , null);
0382:            }
0383:
0384:            /** Checks, whether caret is inside method */
0385:            //    private boolean insideMethod(JTextComponent textComp, int startPos){
0386:            //        try{
0387:            //            int level = 0;
0388:            //            BaseDocument doc = (BaseDocument)textComp.getDocument();
0389:            //            for(int i = startPos-1; i>0; i--){
0390:            //                char ch = doc.getChars(i, 1)[0];
0391:            //                if (ch == ';') return false;
0392:            //                if (ch == ')') level++;
0393:            //                if (ch == '('){
0394:            //                    if (level == 0){
0395:            //                        return true;
0396:            //                    }else{
0397:            //                        level--;
0398:            //                    }
0399:            //                }
0400:            //            }
0401:            //            return false;
0402:            //        } catch (BadLocationException e) {
0403:            //            return false;
0404:            //        }
0405:            //    }
0406:            /** Check and possibly popup, hide or refresh the completion */
0407:            //    public int checkCompletion(JTextComponent target, String typedText, boolean visible ) {
0408:            //        if (!visible) { // pane not visible yet
0409:            //            int dotPos = target.getCaret().getDot();                            
0410:            //            switch (typedText.charAt(0)) {
0411:            //                case ' ':
0412:            //                    BaseDocument doc = (BaseDocument)target.getDocument();
0413:            //                    
0414:            //                    if (dotPos >= 2) { // last char before inserted space
0415:            //                        int pos = Math.max(dotPos - 8, 0);
0416:            //                        try {
0417:            //                            String txtBeforeSpace = doc.getText(pos, dotPos - pos);
0418:            //                            
0419:            //                            if ( txtBeforeSpace.endsWith("import ") // NOI18N
0420:            //                                && !Character.isJavaIdentifierPart(txtBeforeSpace.charAt(0))) {
0421:            //                                return ExtSyntaxSupport.COMPLETION_POPUP;
0422:            //                            }
0423:            //                            
0424:            //                            if (txtBeforeSpace.endsWith(", ")) { // NOI18N
0425:            //                                // autoPopup completion only if caret is inside method
0426:            //                                if (insideMethod(target, dotPos)) return ExtSyntaxSupport.COMPLETION_POPUP;
0427:            //                            }
0428:            //                        } catch (BadLocationException e) {
0429:            //                        }
0430:            //                    }
0431:            //                    break;
0432:            //
0433:            //                case '.':
0434:            //                    return ExtSyntaxSupport.COMPLETION_POPUP;
0435:            //                case ',':
0436:            //                    // autoPopup completion only if caret is inside method
0437:            //                    if (insideMethod(target, dotPos)) return ExtSyntaxSupport.COMPLETION_POPUP;
0438:            //                default:
0439:            //                    if (Character.isJavaIdentifierStart(typedText.charAt(0))) {
0440:            //                        if (dotPos >= 5) { // last char before inserted space
0441:            //                            try {
0442:            //                                String maybeNew = target.getDocument().getText(dotPos - 5, 4);
0443:            //                                if (maybeNew.equals("new ")){ // NOI18N
0444:            //                                    return ExtSyntaxSupport.COMPLETION_POPUP;
0445:            //                                }
0446:            //                            } catch (BadLocationException e) {
0447:            //                            }
0448:            //                        }
0449:            //                    }
0450:            //                }
0451:            //                return ExtSyntaxSupport.COMPLETION_CANCEL;
0452:            //                
0453:            //        } else { // the pane is already visible
0454:            //            switch (typedText.charAt(0)) {
0455:            //                case '=':
0456:            //                case '{':
0457:            //                case ';':
0458:            //                    return ExtSyntaxSupport.COMPLETION_HIDE;
0459:            //                default:
0460:            //                    return ExtSyntaxSupport.COMPLETION_POST_REFRESH;
0461:            //            }
0462:            //        }
0463:            //    }
0464:            public boolean isAssignable(CsmType from, CsmType to) {
0465:                CsmClassifier fromCls = from.getClassifier();
0466:                CsmClassifier toCls = to.getClassifier();
0467:
0468:                // XXX review!
0469:                if (fromCls.equals(CsmCompletion.NULL_CLASS)) {
0470:                    return to.getArrayDepth() > 0
0471:                            || !CsmCompletion.isPrimitiveClass(toCls);
0472:                }
0473:
0474:                if (toCls.equals(CsmCompletion.OBJECT_CLASS)) { // everything is object
0475:                    return (from.getArrayDepth() > to.getArrayDepth())
0476:                            || (from.getArrayDepth() == to.getArrayDepth() && !CsmCompletion
0477:                                    .isPrimitiveClass(fromCls));
0478:                }
0479:
0480:                if (from.getArrayDepth() != to.getArrayDepth()
0481:                        || from.getPointerDepth() != to.getPointerDepth()) {
0482:                    return false;
0483:                }
0484:
0485:                if (fromCls.equals(toCls)) {
0486:                    return true; // equal classes
0487:                }
0488:                String tfrom = from.getCanonicalText().toString().replaceAll(
0489:                        "const", "").trim(); // NOI18N
0490:                String tto = to.getCanonicalText().toString().replaceAll(
0491:                        "const", "").trim(); // NOI18N
0492:
0493:                if (tfrom.equals(tto)) {
0494:                    return true;
0495:                }
0496:                //        if (CsmInheritanceUtilities.isAssignableFrom(toCls, fromCls)) {
0497:                //            return true;
0498:                //        }
0499:                // XXX
0500:                //        if (fromCls.isInterface()) {
0501:                //            return toCls.isInterface()
0502:                //            && (JCUtilities.getAllInterfaces(getFinder(), fromCls).indexOf(toCls) >= 0);
0503:                //        } else { // fromCls is a class
0504:                //            TokenID fromClsKwd = CCTokenContext.getKeyword(fromCls.getName());
0505:                //            if (fromClsKwd != null) { // primitive class
0506:                //                TokenID toClsKwd = CCTokenContext.getKeyword(toCls.getName());
0507:                //                return toClsKwd != null
0508:                //                && JCUtilities.getPrimitivesAssignable(fromClsKwd.getNumericID(), toClsKwd.getNumericID());
0509:                //            } else {
0510:                //                if (toCls.isInterface()) {
0511:                //                    return (JCUtilities.getAllInterfaces(getFinder(), fromCls).indexOf(toCls) >= 0);
0512:                //                } else { // toCls is a class
0513:                //                    return (JCUtilities.getSuperclasses(getFinder(), fromCls).indexOf(toCls) >= 0);
0514:                //                }
0515:                //            }
0516:                //        }
0517:                return false;
0518:            }
0519:
0520:            public CsmType getCommonType(CsmType typ1, CsmType typ2) {
0521:                if (typ1.equals(typ2)) {
0522:                    return typ1;
0523:                }
0524:
0525:                // The following part
0526:                TokenID cls1Kwd = CCTokenContext.getKeyword(typ1
0527:                        .getClassifier().getName().toString());
0528:                TokenID cls2Kwd = CCTokenContext.getKeyword(typ2
0529:                        .getClassifier().getName().toString());
0530:                if (cls1Kwd == null && cls2Kwd == null) { // non-primitive classes
0531:                    if (isAssignable(typ1, typ2)) {
0532:                        return typ1;
0533:                    } else if (isAssignable(typ2, typ1)) {
0534:                        return typ2;
0535:                    } else {
0536:                        return null;
0537:                    }
0538:                } else { // at least one primitive class
0539:                    if (typ1.getArrayDepth() != typ2.getArrayDepth()) {
0540:                        return null;
0541:                    }
0542:                    // XXX review
0543:                    //            if (cls1Kwd != null && cls2Kwd != null) {
0544:                    //                return JavaCompletion.getType(
0545:                    //                JCUtilities.getPrimitivesCommonClass(cls1Kwd.getNumericID(), cls2Kwd.getNumericID()),
0546:                    //                typ1.getArrayDepth());
0547:                    //            } else { // one primitive but other not
0548:                    //                return null;
0549:                    //            }
0550:                    return null;
0551:                }
0552:            }
0553:
0554:            /** Filter the list of the methods (usually returned from
0555:             * Finder.findMethods()) or the list of the constructors
0556:             * by the given parameter specification.
0557:             * @param methodList list of the methods. They should have the same
0558:             *   name but in fact they don't have to.
0559:             * @param parmTypes parameter types specification. If set to null, no filtering
0560:             *   is performed and the same list is returned. If a particular
0561:             * @param acceptMoreParameters useful for code completion to get
0562:             *   even the methods with more parameters.
0563:             */
0564:            public List filterMethods(List methodList, List parmTypeList,
0565:                    boolean acceptMoreParameters) {
0566:                assert (methodList != null);
0567:                if (parmTypeList == null) {
0568:                    return methodList;
0569:                }
0570:
0571:                List ret = new ArrayList();
0572:                int parmTypeCnt = parmTypeList.size();
0573:                int cnt = methodList.size();
0574:                int maxMatched = -1;
0575:                for (int i = 0; i < cnt; i++) {
0576:                    // Use constructor conversion to allow to use it too for the constructors
0577:                    CsmFunction m = (CsmFunction) methodList.get(i);
0578:                    CsmParameter[] methodParms = (CsmParameter[]) m
0579:                            .getParameters().toArray(new CsmParameter[0]);
0580:                    if (methodParms.length == parmTypeCnt
0581:                            || (acceptMoreParameters && methodParms.length >= parmTypeCnt)) {
0582:                        boolean accept = true;
0583:                        boolean bestMatch = !acceptMoreParameters;
0584:                        int matched = 0;
0585:                        for (int j = 0; accept && j < parmTypeCnt; j++) {
0586:                            CsmType mpt = methodParms[j].getType();
0587:                            CsmType t = (CsmType) parmTypeList.get(j);
0588:                            if (t != null) {
0589:                                if (!methodParms[j].isVarArgs()
0590:                                        && !equalTypes(t, mpt)) {
0591:                                    bestMatch = false;
0592:                                    if (!isAssignable(t, mpt)) {
0593:                                        accept = false;
0594:                                        // TODO: do not break now, count matches
0595:                                        // break; 
0596:                                    } else {
0597:                                        matched++;
0598:                                    }
0599:                                } else {
0600:                                    matched++;
0601:                                }
0602:                            } else { // type in list is null
0603:                                bestMatch = false;
0604:                            }
0605:                        }
0606:
0607:                        if (accept) {
0608:                            if (bestMatch) {
0609:                                ret.clear();
0610:                            } else if (matched > maxMatched) {
0611:                                maxMatched = matched;
0612:                                ret.clear();
0613:                            }
0614:                            ret.add(m);
0615:                            if (bestMatch) {
0616:                                break;
0617:                            }
0618:                        } else {
0619:                            if (matched > maxMatched) {
0620:                                maxMatched = matched;
0621:                                ret.clear();
0622:                                ret.add(m);
0623:                            }
0624:                        }
0625:
0626:                    } else if (methodParms.length == 0 && parmTypeCnt == 1) { // for cases like f(void)
0627:                        CsmType t = (CsmType) parmTypeList.get(0);
0628:                        if (t != null && "void".equals(t.getText())) { // best match // NOI18N
0629:                            ret.clear();
0630:                            ret.add(m);
0631:                        }
0632:                    }
0633:                }
0634:                return ret;
0635:            }
0636:
0637:            private boolean isOffsetInToken(TokenItem token,
0638:                    TokenID[] tokenIDs, int offset) {
0639:                boolean exists = false;
0640:                for (int i = tokenIDs.length - 1; i >= 0; i--) {
0641:                    if (token.getTokenID() == tokenIDs[i]) {
0642:                        exists = true;
0643:                        break;
0644:                    }
0645:                }
0646:                if (exists) {
0647:                    // check offset
0648:                    int st = token.getOffset();
0649:                    int len = token.getImage().length();
0650:                    if (st >= offset) {
0651:                        exists = false;
0652:                    } else if (len == 1) {
0653:                        exists = ((st + len) == offset);
0654:                    } else if (token.getTokenID().getCategory() == CCTokenContext.ERRORS) {
0655:                        exists = ((st + len) >= offset);
0656:                    } else {
0657:                        exists = ((st + len) > offset);
0658:                    }
0659:                }
0660:                return exists;
0661:            }
0662:
0663:            /**
0664:             * Interface that can be implemented by the values (in the key-value Map terminology)
0665:             * of the variableMap provided by VariableMapTokenProcessor implementations.
0666:             */
0667:            public interface JavaVariable {
0668:
0669:                /**
0670:                 * Get type expression of the variable declaration.
0671:                 * <br>
0672:                 * For example for "List<String> l;" it would be an expression formed
0673:                 * from "List<String>".
0674:                 *
0675:                 * @return type expression for this variable.
0676:                 */
0677:                public CsmCompletionExpression getTypeExpression();
0678:
0679:                /**
0680:                 * Get variable expression of the variable declaration.
0681:                 * <br>
0682:                 * Typically it is just the declaration variable but for arrays
0683:                 * it can include array depths - for example
0684:                 * for "int i[];" it would be an expression formed
0685:                 * from "i[]".
0686:                 *
0687:                 * @return type expression for this variable.
0688:                 */
0689:                public CsmCompletionExpression getVariableExpression();
0690:
0691:            }
0692:
0693:            public static class CsmDeclarationTokenProcessor implements 
0694:                    DeclarationTokenProcessor, VariableMapTokenProcessor {
0695:
0696:                protected CsmSyntaxSupport sup;
0697:
0698:                /** Position of the begining of the declaration to be returned */
0699:                protected int decStartPos = -1;
0700:
0701:                protected int decArrayDepth;
0702:
0703:                /** Starting position of the declaration type */
0704:                protected int typeStartPos;
0705:
0706:                /** Position of the end of the type */
0707:                protected int typeEndPos;
0708:
0709:                /** Offset of the name of the variable */
0710:                protected int decVarNameOffset;
0711:
0712:                /** Length of the name of the variable */
0713:                protected int decVarNameLen;
0714:
0715:                /** Currently inside parenthesis, i.e. comma delimits declarations */
0716:                protected int parenthesisCounter;
0717:
0718:                /** Depth of the array when there is an array declaration */
0719:                protected int arrayDepth;
0720:
0721:                protected char[] buffer;
0722:
0723:                protected int bufferStartPos;
0724:
0725:                protected String varName;
0726:
0727:                protected int state;
0728:
0729:                /** Map filled with the [varName, type/classifier] pairs */
0730:                protected HashMap varMap;
0731:
0732:                /** Construct new token processor
0733:                 * @param varName it contains valid varName name or null to search
0734:                 *   for all variables and construct the variable map.
0735:                 */
0736:                public CsmDeclarationTokenProcessor(CsmSyntaxSupport sup,
0737:                        String varName) {
0738:                    this .sup = sup;
0739:                    this .varName = varName;
0740:                    if (varName == null) {
0741:                        varMap = new HashMap();
0742:                    }
0743:                }
0744:
0745:                public int getDeclarationPosition() {
0746:                    return decStartPos;
0747:                }
0748:
0749:                public Map getVariableMap() {
0750:                    return varMap;
0751:                }
0752:
0753:                protected void processDeclaration() {
0754:                    // XXX review!
0755:                    if (varName == null) { // collect all variables
0756:                        String decType = new String(buffer, typeStartPos
0757:                                - bufferStartPos, typeEndPos - typeStartPos);
0758:                        if (decType.indexOf(' ') >= 0) {
0759:                            decType = Analyzer.removeSpaces(decType);
0760:                        }
0761:                        String decVarName = new String(buffer,
0762:                                decVarNameOffset, decVarNameLen);
0763:
0764:                        // Maybe it's inner class. Stick an outerClass before it ...
0765:                        CsmClass innerClass = null;
0766:                        CsmClass outerCls = sup.getClass(decVarNameOffset);
0767:                        if (outerCls != null) {
0768:                            String outerClassName = outerCls.getQualifiedName()
0769:                                    .toString();
0770:                            CsmClassifier innerClassifier = sup.getFinder()
0771:                                    .getExactClassifier(
0772:                                            outerClassName
0773:                                                    + CsmCompletion.SCOPE
0774:                                                    + decType);
0775:                            innerClass = CsmKindUtilities
0776:                                    .isClass(innerClassifier) ? (CsmClass) innerClassifier
0777:                                    : null;
0778:                            if (innerClass != null) {
0779:                                //                        varMap.put(decVarName, JavaCompletion.getType(innerClass, decArrayDepth));
0780:                                varMap.put(decVarName, innerClass);
0781:                            }
0782:                        }
0783:
0784:                        if (innerClass == null) {
0785:                            CsmClass cls = sup.getClassFromName(decType, true);
0786:                            if (cls != null) {
0787:                                //                        varMap.put(decVarName, JavaCompletion.getType(cls, decArrayDepth));
0788:                                varMap.put(decVarName, cls);
0789:                            }
0790:                        }
0791:
0792:                    } else {
0793:                        decStartPos = typeStartPos;
0794:                    }
0795:                }
0796:
0797:                public boolean token(TokenID tokenID,
0798:                        TokenContextPath tokenContextPath, int tokenOffset,
0799:                        int tokenLen) {
0800:                    int pos = bufferStartPos + tokenOffset;
0801:
0802:                    // Check whether we are really recognizing the C++ tokens
0803:                    if (!tokenContextPath.contains(CCTokenContext.contextPath)) {
0804:                        state = INIT;
0805:                        return true;
0806:                    }
0807:
0808:                    switch (tokenID.getNumericID()) {
0809:                    case CCTokenContext.BOOLEAN_ID:
0810:                    case CCTokenContext.CHAR_ID:
0811:                    case CCTokenContext.DOUBLE_ID:
0812:                    case CCTokenContext.FLOAT_ID:
0813:                    case CCTokenContext.INT_ID:
0814:                    case CCTokenContext.LONG_ID:
0815:                    case CCTokenContext.SHORT_ID:
0816:                    case CCTokenContext.VOID_ID:
0817:                        typeStartPos = pos;
0818:                        arrayDepth = 0;
0819:                        typeEndPos = pos + tokenLen;
0820:                        state = AFTER_TYPE;
0821:                        break;
0822:
0823:                    case CCTokenContext.DOT_ID:
0824:                    case CCTokenContext.DOTMBR_ID:
0825:                        switch (state) {
0826:                        case AFTER_TYPE: // allowed only inside type
0827:                            state = AFTER_DOT;
0828:                            typeEndPos = pos + tokenLen;
0829:                            break;
0830:
0831:                        case AFTER_EQUAL:
0832:                        case AFTER_VARIABLE:
0833:                            break;
0834:
0835:                        default:
0836:                            state = INIT;
0837:                            break;
0838:                        }
0839:                        break;
0840:
0841:                    case CCTokenContext.ARROW_ID:
0842:                    case CCTokenContext.ARROWMBR_ID:
0843:                        switch (state) {
0844:                        case AFTER_TYPE: // allowed only inside type
0845:                            state = AFTER_ARROW;
0846:                            typeEndPos = pos + tokenLen;
0847:                            break;
0848:
0849:                        case AFTER_EQUAL:
0850:                        case AFTER_VARIABLE:
0851:                            break;
0852:
0853:                        default:
0854:                            state = INIT;
0855:                            break;
0856:                        }
0857:                        break;
0858:
0859:                    case CCTokenContext.SCOPE_ID:
0860:                        switch (state) {
0861:                        case AFTER_TYPE: // allowed only inside type
0862:                            state = AFTER_SCOPE;
0863:                            typeEndPos = pos + tokenLen;
0864:                            break;
0865:
0866:                        case AFTER_EQUAL:
0867:                        case AFTER_VARIABLE:
0868:                            break;
0869:
0870:                        default:
0871:                            state = INIT;
0872:                            break;
0873:                        }
0874:                        break;
0875:                    //XXX
0876:                    //                case CCTokenContext.ELLIPSIS_ID:
0877:                    //                    switch (state) {
0878:                    //                        case AFTER_TYPE:
0879:                    //                            arrayDepth++;
0880:                    //                            break;
0881:                    //
0882:                    //                        default:
0883:                    //                            state = INIT;
0884:                    //                            break;
0885:                    //                    }
0886:                    //                    break;
0887:
0888:                    case CCTokenContext.LBRACKET_ID:
0889:                        switch (state) {
0890:                        case AFTER_TYPE:
0891:                            state = AFTER_TYPE_LSB;
0892:                            arrayDepth++;
0893:                            break;
0894:
0895:                        case AFTER_MATCHING_VARIABLE:
0896:                            state = AFTER_MATCHING_VARIABLE_LSB;
0897:                            decArrayDepth++;
0898:                            break;
0899:
0900:                        case AFTER_EQUAL:
0901:                            break;
0902:
0903:                        default:
0904:                            state = INIT;
0905:                            break;
0906:                        }
0907:                        break;
0908:
0909:                    case CCTokenContext.RBRACKET_ID:
0910:                        switch (state) {
0911:                        case AFTER_TYPE_LSB:
0912:                            state = AFTER_TYPE;
0913:                            break;
0914:
0915:                        case AFTER_MATCHING_VARIABLE_LSB:
0916:                            state = AFTER_MATCHING_VARIABLE;
0917:                            break;
0918:
0919:                        case AFTER_EQUAL:
0920:                            break;
0921:
0922:                        default:
0923:                            state = INIT;
0924:                            break;
0925:                        }
0926:                        break; // both in type and varName
0927:
0928:                    case CCTokenContext.LPAREN_ID:
0929:                        parenthesisCounter++;
0930:                        if (state != AFTER_EQUAL) {
0931:                            state = INIT;
0932:                        }
0933:                        break;
0934:
0935:                    case CCTokenContext.RPAREN_ID:
0936:                        if (state == AFTER_MATCHING_VARIABLE) {
0937:                            processDeclaration();
0938:                        }
0939:                        if (parenthesisCounter > 0) {
0940:                            parenthesisCounter--;
0941:                        }
0942:                        if (state != AFTER_EQUAL) {
0943:                            state = INIT;
0944:                        }
0945:                        break;
0946:
0947:                    case CCTokenContext.LBRACE_ID:
0948:                    case CCTokenContext.RBRACE_ID:
0949:                        if (parenthesisCounter > 0) {
0950:                            parenthesisCounter--; // to tolerate opened parenthesis
0951:                        }
0952:                        state = INIT;
0953:                        break;
0954:
0955:                    case CCTokenContext.COMMA_ID:
0956:                        if (parenthesisCounter > 0) { // comma is declaration separator in parenthesis
0957:                            if (parenthesisCounter == 1
0958:                                    && state == AFTER_MATCHING_VARIABLE) {
0959:                                processDeclaration();
0960:                            }
0961:                            if (state != AFTER_EQUAL) {
0962:                                state = INIT;
0963:                            }
0964:                        } else { // not in parenthesis
0965:                            switch (state) {
0966:                            case AFTER_MATCHING_VARIABLE:
0967:                                processDeclaration();
0968:                                // let it flow to AFTER_VARIABLE
0969:                            case AFTER_VARIABLE:
0970:                            case AFTER_EQUAL:
0971:                                state = AFTER_COMMA;
0972:                                break;
0973:
0974:                            default:
0975:                                state = INIT;
0976:                                break;
0977:                            }
0978:                        }
0979:                        break;
0980:
0981:                    case CCTokenContext.NEW_ID:
0982:                        if (state != AFTER_EQUAL) {
0983:                            state = INIT;
0984:                        }
0985:                        break;
0986:
0987:                    case CCTokenContext.EQ_ID:
0988:                        switch (state) {
0989:                        case AFTER_MATCHING_VARIABLE:
0990:                            processDeclaration();
0991:                            // flow to AFTER_VARIABLE
0992:
0993:                        case AFTER_VARIABLE:
0994:                            state = AFTER_EQUAL;
0995:                            break;
0996:
0997:                        case AFTER_EQUAL:
0998:                            break;
0999:
1000:                        default:
1001:                            state = INIT;
1002:                        }
1003:                        break;
1004:
1005:                    case CCTokenContext.SEMICOLON_ID:
1006:                        if (state == AFTER_MATCHING_VARIABLE) {
1007:                            processDeclaration();
1008:                        }
1009:                        state = INIT;
1010:                        break;
1011:
1012:                    case CCTokenContext.IDENTIFIER_ID:
1013:                        switch (state) {
1014:                        case AFTER_TYPE:
1015:                        case AFTER_COMMA:
1016:                            if (varName == null
1017:                                    || Analyzer.equals(varName, buffer,
1018:                                            tokenOffset, tokenLen)) {
1019:                                decArrayDepth = arrayDepth;
1020:                                decVarNameOffset = tokenOffset;
1021:                                decVarNameLen = tokenLen;
1022:                                state = AFTER_MATCHING_VARIABLE;
1023:                            } else {
1024:                                state = AFTER_VARIABLE;
1025:                            }
1026:                            break;
1027:
1028:                        case AFTER_VARIABLE: // error
1029:                            state = INIT;
1030:                            break;
1031:
1032:                        case AFTER_EQUAL:
1033:                            break;
1034:
1035:                        case AFTER_DOT:
1036:                            typeEndPos = pos + tokenLen;
1037:                            state = AFTER_TYPE;
1038:                            break;
1039:
1040:                        case AFTER_ARROW:
1041:                            typeEndPos = pos + tokenLen;
1042:                            state = AFTER_VARIABLE;
1043:                            break;
1044:
1045:                        case AFTER_SCOPE: // only valid after type
1046:                            typeEndPos = pos + tokenLen;
1047:                            state = AFTER_TYPE;
1048:                            break;
1049:
1050:                        case INIT:
1051:                            typeStartPos = pos;
1052:                            arrayDepth = 0;
1053:                            typeEndPos = pos + tokenLen;
1054:                            state = AFTER_TYPE;
1055:                            break;
1056:
1057:                        default:
1058:                            state = INIT;
1059:                            break;
1060:                        }
1061:                        break;
1062:
1063:                    case CCTokenContext.WHITESPACE_ID: // whitespace ignored
1064:                        break;
1065:
1066:                    case CCTokenContext.COLON_ID: // 1.5 enhanced for loop sysntax
1067:                        processDeclaration();
1068:
1069:                        //                case CCTokenContext.INSTANCEOF_ID:
1070:                    default:
1071:                        state = INIT;
1072:                    }
1073:
1074:                    return true;
1075:                }
1076:
1077:                public int eot(int offset) {
1078:                    return 0;
1079:                }
1080:
1081:                public void nextBuffer(char[] buffer, int offset, int len,
1082:                        int startPos, int preScan, boolean lastBuffer) {
1083:                    this .buffer = buffer;
1084:                    bufferStartPos = startPos - offset;
1085:                }
1086:
1087:            }
1088:
1089:            ////////////////////////////////////////////////
1090:            // overriden functions to resolve expressions
1091:            /////////////////////////////////////////////////
1092:
1093:            /** Map holding the [position, class-fields-map] pairs */
1094:            private HashMap classFieldMaps = new HashMap();
1095:
1096:            /** Map holding the [position, class-fields-map] pairs */
1097:            private HashMap fileVariableMaps = new HashMap();
1098:
1099:            /** Find the type of the variable. The default behavior is to first
1100:             * search for the local variable declaration and then possibly for
1101:             * the global declaration and if the declaration position is found
1102:             * to get the first word on that position.
1103:             * @return it returns Object to enable the custom implementations
1104:             *   to return the appropriate instances.
1105:             */
1106:            @Override
1107:            public Object findType(String varName, int varPos) {
1108:                CsmType type = null;
1109:                Map varMap = getLocalVariableMap(varPos); // first try local vars
1110:                if (varMap != null) {
1111:                    type = (CsmType) varMap.get(varName);
1112:                }
1113:
1114:                // then try class fields
1115:                if (type == null) {
1116:                    varMap = getClassFieldMap(varPos); // try class fields
1117:                    if (varMap != null) {
1118:                        type = (CsmType) varMap.get(varName);
1119:                    }
1120:                }
1121:
1122:                // then try file local vars
1123:                if (type == null) {
1124:                    varMap = getFileVariableMap(varPos); // try file local vars
1125:                    if (varMap != null) {
1126:                        type = (CsmType) varMap.get(varName);
1127:                    }
1128:                }
1129:
1130:                // at the end - globals
1131:                if (type == null) {
1132:                    varMap = getGlobalVariableMap(varPos); // try global vars
1133:                    if (varMap != null) {
1134:                        type = (CsmType) varMap.get(varName);
1135:                    }
1136:                }
1137:
1138:                return type;
1139:            }
1140:
1141:            public Map getClassFieldMap(int offset) {
1142:                Integer posI = new Integer(offset);
1143:                Map varMap = (Map) classFieldMaps.get(posI);
1144:                if (varMap == null) {
1145:                    varMap = buildClassFieldMap(offset);
1146:                    classFieldMaps.put(posI, varMap);
1147:                }
1148:                return varMap;
1149:            }
1150:
1151:            public Map getFileVariableMap(int offset) {
1152:                Integer posI = new Integer(offset);
1153:                Map varMap = (Map) fileVariableMaps.get(posI);
1154:                if (varMap == null) {
1155:                    varMap = buildFileVariableMap(offset);
1156:                    fileVariableMaps.put(posI, varMap);
1157:                }
1158:                return varMap;
1159:            }
1160:
1161:            ///////////////////////////////////////////////////////////////////////////
1162:            //                  build variable maps
1163:            ///////////////////////////////////////////////////////////////////////////
1164:
1165:            @Override
1166:            protected Map buildLocalVariableMap(int offset) {
1167:                int methodStartPos = getMethodStartPosition(offset);
1168:                if (methodStartPos >= 0 && methodStartPos < offset) {
1169:                    List res = CompletionUtilities.findFunctionLocalVariables(
1170:                            getDocument(), offset);
1171:                    return list2Map(res);
1172:                }
1173:                return null;
1174:            }
1175:
1176:            @Override
1177:            protected Map buildGlobalVariableMap(int offset) {
1178:                List res = CompletionUtilities.findGlobalVariables(
1179:                        getDocument(), offset);
1180:                return list2Map(res);
1181:            }
1182:
1183:            protected Map buildClassFieldMap(int offset) {
1184:                List res = CompletionUtilities.findClassFields(getDocument(),
1185:                        offset);
1186:                return list2Map(res);
1187:            }
1188:
1189:            protected Map buildFileVariableMap(int offset) {
1190:                List res = CompletionUtilities.findFileVariables(getDocument(),
1191:                        offset);
1192:                return list2Map(res);
1193:            }
1194:
1195:            // utitlies
1196:
1197:            private Map/*<var-name, CsmType>*/list2Map(
1198:                    List/*<CsmVariable>*/vars) {
1199:                if (vars == null || vars.size() == 0) {
1200:                    return null;
1201:                }
1202:                Map res = new StringMap();
1203:                for (Iterator it = vars.iterator(); it.hasNext();) {
1204:                    Object elem = it.next();
1205:                    if (elem instanceof  CsmVariable) {
1206:                        CsmVariable var = (CsmVariable) elem;
1207:                        res.put(var.getName().toString(), var.getType());
1208:                    }
1209:                }
1210:                return res;
1211:            }
1212:
1213:            @Override
1214:            protected boolean isAbbrevDisabled(int offset) {
1215:                boolean abbrevDisabled = false;
1216:                TokenID[] disableTokenIds = BRACKET_SKIP_TOKENS;
1217:                if (disableTokenIds != null) {
1218:                    TokenItem token;
1219:                    try {
1220:                        token = getTokenChain(offset, offset + 1);
1221:                    } catch (BadLocationException e) {
1222:                        token = null;
1223:                    }
1224:                    if (token != null) {
1225:                        if (offset > token.getOffset()) { // not right at token's begining
1226:                            for (int i = disableTokenIds.length - 1; i >= 0; i--) {
1227:                                if (token.getTokenID() == disableTokenIds[i]) {
1228:                                    abbrevDisabled = true;
1229:                                    break;
1230:                                }
1231:                            }
1232:                        }
1233:                        if (!abbrevDisabled) { // check whether not right after line comment
1234:                            if (token.getOffset() == offset) {
1235:                                TokenItem prevToken = token.getPrevious();
1236:                                if (prevToken != null
1237:                                        && prevToken.getTokenID() == CCTokenContext.LINE_COMMENT) {
1238:                                    abbrevDisabled = true;
1239:                                }
1240:                            }
1241:                        }
1242:                    }
1243:                }
1244:                return abbrevDisabled;
1245:            }
1246:
1247:            public boolean isIncludeCompletionDisabled(int offset) {
1248:                boolean completionDisabled = true;
1249:                TokenItem token = getTokenItem(offset);
1250:                token = shiftToNonWhiteBwd(token);
1251:                if (token != null) {
1252:                    completionDisabled = !isOffsetInToken(token,
1253:                            INCLUDE_COMPLETION_TOKENS, offset);
1254:                    if (completionDisabled) {
1255:                        // check whether right after #include or #include_next directive
1256:                        switch (token.getTokenID().getNumericID()) {
1257:                        case CCTokenContext.CPPINCLUDE_ID:
1258:                        case CCTokenContext.CPPINCLUDE_NEXT_ID:
1259:                            return completionDisabled = false;
1260:                        }
1261:                    }
1262:                }
1263:                return completionDisabled;
1264:            }
1265:
1266:            public TokenItem getTokenItem(int offset) {
1267:                TokenItem token;
1268:                try {
1269:                    int checkOffset = offset;
1270:                    if (offset == getDocument().getLength()) {
1271:                        if (offset == 0) {
1272:                            return null;
1273:                        }
1274:                        checkOffset--;
1275:                    }
1276:                    token = getTokenChain(checkOffset, checkOffset + 1);
1277:                } catch (BadLocationException e) {
1278:                    token = null;
1279:                }
1280:                return token;
1281:            }
1282:
1283:            public TokenItem shiftToNonWhiteBwd(TokenItem token) {
1284:                if (token == null) {
1285:                    return null;
1286:                }
1287:                boolean checkedFirst = false;
1288:                do {
1289:                    switch (token.getTokenID().getNumericID()) {
1290:                    case CCTokenContext.WHITESPACE_ID:
1291:                        if (checkedFirst) {
1292:                            if (token.getImage().contains("\n")) { // NOI18N
1293:                                return null;
1294:                            }
1295:                        }
1296:                        break;
1297:                    case CCTokenContext.BLOCK_COMMENT_ID:
1298:                        // skip
1299:                        break;
1300:                    default:
1301:                        return token;
1302:                    }
1303:                    token = token.getPrevious();
1304:                    checkedFirst = true;
1305:                } while (token != null);
1306:                return null;
1307:            }
1308:
1309:            private boolean isAfterInclude(int offset) {
1310:                try {
1311:                    if (offset == getDocument().getLength()) {
1312:                        offset--;
1313:                    }
1314:                    int rowStart = Utilities.getRowStart(getDocument(), offset);
1315:                    TokenItem item = getTokenChain(rowStart, rowStart + 1);
1316:                    if (item != null) {
1317:                        switch (item.getTokenID().getNumericID()) {
1318:                        case CCTokenContext.CPPINCLUDE_ID:
1319:                        case CCTokenContext.CPPINCLUDE_NEXT_ID:
1320:                            while (item != null) {
1321:                                item = item.getNext();
1322:                                if (item != null
1323:                                        && (item.getOffset() < offset)
1324:                                        && (item.getTokenID() != CCTokenContext.WHITESPACE)) {
1325:                                    return false;
1326:                                }
1327:                            }
1328:                            return true;
1329:                        }
1330:                    }
1331:                } catch (BadLocationException ex) {
1332:                    // skip
1333:                }
1334:                return false;
1335:            }
1336:
1337:            public boolean isCompletionDisabled(int offset) {
1338:                boolean completionDisabled = false;
1339:                TokenID[] disableTokenIds = COMPLETION_SKIP_TOKENS;
1340:                if (disableTokenIds != null) {
1341:                    TokenItem token;
1342:                    try {
1343:                        token = getTokenChain(offset, offset + 1);
1344:                    } catch (BadLocationException e) {
1345:                        token = null;
1346:                    }
1347:                    if (token != null) {
1348:                        if (offset > token.getOffset()) { // not right at token's begining
1349:                            for (int i = disableTokenIds.length - 1; i >= 0; i--) {
1350:                                if (token.getTokenID() == disableTokenIds[i]) {
1351:                                    completionDisabled = true;
1352:                                    break;
1353:                                }
1354:                            }
1355:                        }
1356:                        if (!completionDisabled) { // check whether not right after line comment or float constant
1357:                            if (token.getOffset() == offset) {
1358:                                TokenItem prevToken = token.getPrevious();
1359:                                if (prevToken != null
1360:                                        && (prevToken.getTokenID() == CCTokenContext.LINE_COMMENT
1361:                                                || prevToken.getTokenID() == CCTokenContext.FLOAT_LITERAL || prevToken
1362:                                                .getTokenID() == CCTokenContext.DOUBLE_LITERAL)) {
1363:                                    completionDisabled = true;
1364:                                }
1365:                            }
1366:                        }
1367:                    }
1368:                }
1369:                return completionDisabled;
1370:            }
1371:
1372:            public boolean needShowCompletionOnText(JTextComponent target,
1373:                    String typedText) throws BadLocationException {
1374:                boolean showCompletion = false;
1375:                char typedChar = typedText.charAt(0);
1376:                if (typedChar == ' ' || typedChar == '>' || typedChar == ':'
1377:                        || typedChar == '.' || typedChar == '*') {
1378:
1379:                    int dotPos = target.getCaret().getDot();
1380:                    BaseDocument doc = (BaseDocument) target.getDocument();
1381:                    TokenItem item = getTokenChain(dotPos - 1, dotPos);
1382:                    TokenItem prev = null;
1383:                    if (typedChar == ' ' || typedChar == '.') { // init prev for space and dot
1384:                        try {
1385:                            prev = item == null ? null : item.getPrevious();
1386:                        } catch (IllegalStateException ex) {
1387:                            prev = null;
1388:                        }
1389:                    }
1390:                    switch (typedChar) {
1391:                    case ' ': // completion after "new" keyword
1392:                        if (prev != null
1393:                                && prev.getTokenID() == CCTokenContext.NEW) {
1394:                            showCompletion = true;
1395:                        }
1396:                        break;
1397:                    case '>': // completion after arrow
1398:                        if (item != null
1399:                                && item.getTokenID() == CCTokenContext.ARROW) {
1400:                            showCompletion = true;
1401:                        }
1402:                        break;
1403:                    case '.': // completion after dot
1404:                        showCompletion = true;
1405:                        // hide completion in inlclude strings
1406:                        if (item != null
1407:                                && (item.getTokenID().getCategory() == CCTokenContext.ERRORS
1408:                                        || item.getTokenID() == CCTokenContext.USR_INCLUDE || item
1409:                                        .getTokenID() == CCTokenContext.SYS_INCLUDE)) {
1410:                            showCompletion = false;
1411:                        } else if (prev != null
1412:                                && prev.getTokenID() == CCTokenContext.DOT) {
1413:                            showCompletion = false;
1414:                        }
1415:                        break;
1416:                    case '*': // completion after star
1417:                        if (item != null
1418:                                && (item.getTokenID() == CCTokenContext.ARROWMBR || item
1419:                                        .getTokenID() == CCTokenContext.DOTMBR)) {
1420:                            showCompletion = true;
1421:                        }
1422:                        break;
1423:                    case ':': // completion after scope
1424:                        if (item != null
1425:                                && item.getTokenID() == CCTokenContext.SCOPE) {
1426:                            showCompletion = true;
1427:                        }
1428:                        break;
1429:                    }
1430:                }
1431:                return showCompletion;
1432:            }
1433:
1434:            private boolean equalTypes(CsmType t, CsmType mpt) {
1435:                assert t != null;
1436:                if (t.equals(mpt)) {
1437:                    return true;
1438:                } else if (mpt != null) {
1439:                    String t1 = t.getCanonicalText().toString();
1440:                    String t2 = mpt.getCanonicalText().toString();
1441:                    return t1.equals(t2);
1442:                }
1443:                return false;
1444:            }
1445:        }
www_.ja__va___2___s.c___o__m_ | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.