Source Code Cross Referenced for CCFormatSupport.java in  » IDE-Netbeans » cnd » org » netbeans » modules » cnd » editor » cplusplus » 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.editor.cplusplus 
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 2001-2006 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.editor.cplusplus;
0043:
0044:        import org.netbeans.editor.TokenID;
0045:        import org.netbeans.editor.TokenItem;
0046:        import org.netbeans.editor.TokenContextPath;
0047:        import org.netbeans.editor.ext.FormatTokenPosition;
0048:        import org.netbeans.editor.ext.ExtFormatSupport;
0049:        import org.netbeans.editor.ext.FormatWriter;
0050:        import org.netbeans.modules.cnd.editor.api.CodeStyle;
0051:        import org.openide.util.NbBundle;
0052:
0053:        /**
0054:         * CC indentation services are located here
0055:         *
0056:         * duped from editor/libsrc/org/netbeans/editor/ext/java/JavaFormatSupport.java
0057:         */
0058:        public class CCFormatSupport extends ExtFormatSupport {
0059:
0060:            private TokenContextPath tokenContextPath;
0061:            private CodeStyle.Language language;
0062:
0063:            public CCFormatSupport(CodeStyle.Language language,
0064:                    FormatWriter formatWriter) {
0065:                this (language, formatWriter, CCTokenContext.contextPath);
0066:            }
0067:
0068:            private CCFormatSupport(CodeStyle.Language language,
0069:                    FormatWriter formatWriter, TokenContextPath tokenContextPath) {
0070:                super (formatWriter);
0071:                this .tokenContextPath = tokenContextPath;
0072:                this .language = language;
0073:            }
0074:
0075:            public TokenContextPath getTokenContextPath() {
0076:                return tokenContextPath;
0077:            }
0078:
0079:            @Override
0080:            public boolean isComment(TokenItem token, int offset) {
0081:                TokenID tokenID = token.getTokenID();
0082:                return (token.getTokenContextPath() == tokenContextPath && (tokenID == CCTokenContext.LINE_COMMENT || tokenID == CCTokenContext.BLOCK_COMMENT));
0083:            }
0084:
0085:            /** Is given token a preprocessor **/
0086:            public boolean isPreprocessorAtLineStart(TokenItem token) {
0087:                if (getFormatSpaceBeforeMethodCallParenthesis())
0088:                    return false;
0089:                if (token != null) {
0090:                    FormatTokenPosition ft = findLineFirstNonWhitespace(getPosition(
0091:                            token, 0));
0092:                    if (ft != null) {
0093:                        token = ft.getToken();
0094:                    }
0095:                }
0096:                return (token != null && token.getImage().startsWith("#")); // NOI18N
0097:                //&& getVisualColumnOffset(getPosition(token,0)) == 0);
0098:            }
0099:
0100:            /** Is given token a preprocessor **/
0101:            public boolean isPreprocessorLine(TokenItem token) {
0102:                if (token != null) {
0103:                    FormatTokenPosition ft = findLineFirstNonWhitespace(getPosition(
0104:                            token, 0));
0105:                    if (ft != null) {
0106:                        if (isEndBackSlashedLine(ft)) {
0107:                            FormatTokenPosition eol = findPreviousEOL(ft);
0108:                            ft = eol;
0109:                            while (eol != null) {
0110:                                if (isBackSlashEndLine(eol)) {
0111:                                    ft = eol;
0112:                                    eol = findPreviousEOL(eol);
0113:                                } else {
0114:                                    break;
0115:                                }
0116:                            }
0117:                            ft = findLineFirstNonWhitespace(ft);
0118:                        } else if (isBackSlashEndLine(ft)) {
0119:                            FormatTokenPosition eol = ft;
0120:                            eol = findPreviousEOL(eol);
0121:                            while (eol != null) {
0122:                                if (isBackSlashEndLine(eol)) {
0123:                                    ft = eol;
0124:                                    eol = findPreviousEOL(eol);
0125:                                } else {
0126:                                    break;
0127:                                }
0128:                            }
0129:                            ft = findLineFirstNonWhitespace(ft);
0130:                        }
0131:                        if (ft != null) {
0132:                            token = ft.getToken();
0133:                        }
0134:                    }
0135:                }
0136:                return (token != null && token.getImage().startsWith("#")); // NOI18N
0137:            }
0138:
0139:            /** Return the ending non whitespace on the line or null
0140:             * if there's no such token on the given line.
0141:             */
0142:            public boolean isEndBackSlashedLine(FormatTokenPosition pos) {
0143:                FormatTokenPosition eol = findPreviousEOL(pos);
0144:                if (eol != null) {
0145:                    TokenItem token = eol.getToken();
0146:                    if (token != null) {
0147:                        eol = findLineFirstNonWhitespace(getPosition(token, 0));
0148:                        if (eol != null) {
0149:                            return isBackSlashEndLine(eol);
0150:                        }
0151:                    }
0152:                }
0153:                return false;
0154:            }
0155:
0156:            /** Return the ending non whitespace on the line or null
0157:             * if there's no such token on the given line.
0158:             */
0159:            public boolean isBackSlashEndLine(FormatTokenPosition pos) {
0160:                FormatTokenPosition eol = findLineEndNonImportant(pos);
0161:                if (eol != null) {
0162:                    TokenItem token = eol.getToken();
0163:                    if (token != null) {
0164:                        if (token.getTokenID() == CCTokenContext.BACKSLASH
0165:                                || token.getTokenID() == CCTokenContext.INVALID_BACKSLASH) {
0166:                            return true;
0167:                        }
0168:                        token = token.getPrevious();
0169:                        return token != null
0170:                                && (token.getTokenID() == CCTokenContext.BACKSLASH || token
0171:                                        .getTokenID() == CCTokenContext.INVALID_BACKSLASH);
0172:                    }
0173:                }
0174:                return false;
0175:            }
0176:
0177:            public boolean isMultiLineComment(TokenItem token) {
0178:                return (token.getTokenID() == CCTokenContext.BLOCK_COMMENT);
0179:            }
0180:
0181:            public boolean isMultiLineComment(FormatTokenPosition pos) {
0182:                TokenItem token = pos.getToken();
0183:                return (token == null) ? false : isMultiLineComment(token);
0184:            }
0185:
0186:            /** Check whether the given token is multi-line comment
0187:             * that starts with a slash and an asterisk.
0188:             */
0189:            public boolean isCCDocComment(TokenItem token) {
0190:                return isMultiLineComment(token)
0191:                        && token.getImage().startsWith("/*");
0192:            }
0193:
0194:            @Override
0195:            public TokenID getWhitespaceTokenID() {
0196:                return CCTokenContext.WHITESPACE;
0197:            }
0198:
0199:            @Override
0200:            public TokenContextPath getWhitespaceTokenContextPath() {
0201:                return tokenContextPath;
0202:            }
0203:
0204:            @Override
0205:            public boolean canModifyWhitespace(TokenItem inToken) {
0206:                if (inToken.getTokenContextPath() == CCTokenContext.contextPath) {
0207:                    switch (inToken.getTokenID().getNumericID()) {
0208:                    case CCTokenContext.BLOCK_COMMENT_ID:
0209:                    case CCTokenContext.WHITESPACE_ID:
0210:                        return true;
0211:                    }
0212:                }
0213:                return false;
0214:            }
0215:
0216:            /** Find the starting token of the statement before
0217:             * the given position and also return all the command
0218:             * delimiters. It searches in the backward direction
0219:             * for all the delimiters and statement starts and
0220:             * return all the tokens that are either command starts
0221:             * or delimiters. As the first step it uses
0222:             * <code>getPreviousToken()</code> so it ignores the initial token.
0223:             * @param token token before which the statement-start
0224:             *  and delimiter is being searched.
0225:             * @return token that is start of the given statement
0226:             *  or command delimiter.
0227:             *  If the start of the statement is not found, null is returned.
0228:             */
0229:            public TokenItem findStatement(TokenItem token) {
0230:                TokenItem lit = null; // last important token
0231:                boolean firstColon = true;
0232:                TokenItem t = getPreviousToken(token);
0233:
0234:                while (t != null) {
0235:                    if (t.getTokenContextPath() == tokenContextPath) {
0236:
0237:                        switch (t.getTokenID().getNumericID()) {
0238:                        case CCTokenContext.SEMICOLON_ID:
0239:                            if (!isForLoopSemicolon(t)) {
0240:                                return (lit != null) ? lit : t;
0241:                            }
0242:                            break;
0243:
0244:                        case CCTokenContext.LBRACE_ID:
0245:                        case CCTokenContext.ELSE_ID:
0246:                            return (lit != null) ? lit : t;
0247:
0248:                        case CCTokenContext.RBRACE_ID:
0249:                            // Check whether this is an array initialization block
0250:                            if (!isArrayInitializationBraceBlock(t, null)) {
0251:                                return (lit != null) ? lit : t;
0252:                            } else { // skip the array initialization block
0253:                                t = findMatchingToken(t, null,
0254:                                        CCTokenContext.LBRACE, true);
0255:                            }
0256:                            break;
0257:
0258:                        case CCTokenContext.COLON_ID:
0259:                            TokenItem tt = findAnyToken(t, null, new TokenID[] {
0260:                                    CCTokenContext.CASE,
0261:                                    CCTokenContext.DEFAULT,
0262:                                    CCTokenContext.QUESTION }, t
0263:                                    .getTokenContextPath(), true);
0264:                            if (tt != null) {
0265:                                switch (tt.getTokenID().getNumericID()) {
0266:                                case CCTokenContext.CASE_ID:
0267:                                case CCTokenContext.DEFAULT_ID:
0268:                                    return (lit != null) ? lit : t;
0269:                                }
0270:                            }
0271:                            TokenItem prev = findImportantToken(t, null, true,
0272:                                    true);
0273:                            if (prev != null
0274:                                    && prev.getTokenID().getNumericID() == CCTokenContext.RPAREN_ID) {
0275:                                t = prev;
0276:                                break;
0277:                            }
0278:                            if (lit != null && firstColon && tt == null) {
0279:                                return lit;
0280:                            }
0281:                            firstColon = false;
0282:                            break;
0283:
0284:                        case CCTokenContext.DO_ID:
0285:                        case CCTokenContext.SWITCH_ID:
0286:                        case CCTokenContext.CASE_ID:
0287:                        case CCTokenContext.DEFAULT_ID:
0288:                            return t;
0289:
0290:                        case CCTokenContext.FOR_ID:
0291:                        case CCTokenContext.IF_ID:
0292:                        case CCTokenContext.WHILE_ID:
0293:                            /* Try to find the statement after ( ... )
0294:                             * If it exists, then the first important
0295:                             * token after it is the stmt start. Otherwise
0296:                             * it's this token.
0297:                             */
0298:                            if (lit != null
0299:                                    && lit.getTokenID() == CCTokenContext.LPAREN) {
0300:                                // Find matching right paren in fwd dir
0301:                                TokenItem mt = findMatchingToken(lit, token,
0302:                                        CCTokenContext.RPAREN, false);
0303:                                if (mt != null && mt.getNext() != null) {
0304:                                    mt = findImportantToken(mt.getNext(),
0305:                                            token, false, true);
0306:                                    if (mt != null) {
0307:                                        return mt;
0308:                                    }
0309:                                }
0310:                            }
0311:                            // No further stmt found, return this one
0312:                            return t;
0313:                        }
0314:                        // Remember last important token (preprocessor token are not important (?) (4922370))
0315:                        if (!isPreprocessorLine(t) && isImportant(t, 0)) {
0316:                            lit = t;
0317:                        }
0318:                    }
0319:                    t = t.getPrevious();
0320:                }
0321:                return lit;
0322:            }
0323:
0324:            /**
0325:             * Find the 'if' when the 'else' is provided.
0326:             * @param elseToken the token with the 'else' command
0327:             *  for which the 'if' is being searched.
0328:             * @return corresponding 'if' token or null if there's
0329:             *  no corresponding 'if' statement.
0330:             */
0331:            public TokenItem findIf(TokenItem elseToken) {
0332:                if (elseToken == null
0333:                        || !tokenEquals(elseToken, CCTokenContext.ELSE,
0334:                                tokenContextPath)) {
0335:                    throw new IllegalArgumentException(NbBundle.getBundle(
0336:                            CCFormatSupport.class).getString(
0337:                            "MSG_AcceptOnlyElse")); //NOI18N
0338:                }
0339:
0340:                int braceDepth = 0; // depth of the braces
0341:                int elseDepth = 0; // depth of multiple else stmts
0342:                while (true) {
0343:                    elseToken = findStatement(elseToken);
0344:                    if (elseToken == null) {
0345:                        return null;
0346:                    }
0347:
0348:                    switch (elseToken.getTokenID().getNumericID()) {
0349:                    case CCTokenContext.LBRACE_ID:
0350:                        if (--braceDepth < 0) {
0351:                            return null; // no corresponding right brace
0352:                        }
0353:                        break;
0354:
0355:                    case CCTokenContext.RBRACE_ID:
0356:                        braceDepth++;
0357:                        break;
0358:
0359:                    case CCTokenContext.ELSE_ID:
0360:                        if (braceDepth == 0) {
0361:                            elseDepth++;
0362:                        }
0363:                        break;
0364:
0365:                    case CCTokenContext.SEMICOLON_ID:
0366:                    case CCTokenContext.COLON_ID:
0367:                    case CCTokenContext.DO_ID:
0368:                    case CCTokenContext.CASE_ID:
0369:                    case CCTokenContext.DEFAULT_ID:
0370:                    case CCTokenContext.FOR_ID:
0371:                    case CCTokenContext.WHILE_ID:
0372:                        break;
0373:
0374:                    case CCTokenContext.IF_ID:
0375:                        if (braceDepth == 0) {
0376:                            if (elseDepth-- == 0) {
0377:                                return elseToken; // successful search
0378:                            }
0379:                        }
0380:                        break;
0381:                    }
0382:                }
0383:            }
0384:
0385:            /** Find the 'switch' when the 'case' is provided.
0386:             * @param caseToken the token with the 'case' command
0387:             *  for which the 'switch' is being searched.
0388:             * @return corresponding 'switch' token or null if there's
0389:             *  no corresponding 'switch' statement.
0390:             */
0391:            public TokenItem findSwitch(TokenItem caseToken) {
0392:                if (caseToken == null
0393:                        || (!tokenEquals(caseToken, CCTokenContext.CASE,
0394:                                tokenContextPath) && !tokenEquals(caseToken,
0395:                                CCTokenContext.DEFAULT, tokenContextPath))) {
0396:                    throw new IllegalArgumentException(NbBundle.getBundle(
0397:                            CCFormatSupport.class).getString(
0398:                            "MSG_AcceptOlyCaseDefault")); //NOI18N
0399:                }
0400:
0401:                int braceDepth = 1; // depth of the braces - need one more left
0402:                while (true) {
0403:                    caseToken = findStatement(caseToken);
0404:                    if (caseToken == null) {
0405:                        return null;
0406:                    }
0407:
0408:                    switch (caseToken.getTokenID().getNumericID()) {
0409:                    case CCTokenContext.LBRACE_ID:
0410:                        if (--braceDepth < 0) {
0411:                            return null; // no corresponding right brace
0412:                        }
0413:                        break;
0414:
0415:                    case CCTokenContext.RBRACE_ID:
0416:                        braceDepth++;
0417:                        break;
0418:
0419:                    case CCTokenContext.SWITCH_ID:
0420:                    case CCTokenContext.DEFAULT_ID:
0421:                        if (braceDepth == 0) {
0422:                            return caseToken;
0423:                        }
0424:                        break;
0425:                    }
0426:                }
0427:            }
0428:
0429:            /** Find the 'class' or 'struct'
0430:             * @param visibilityToken the token.
0431:             */
0432:            private TokenItem findClassifier(TokenItem visibilityToken) {
0433:                int braceDepth = 1; // depth of the braces - need one more left
0434:                TokenItem classifierToken = visibilityToken;
0435:                while (true) {
0436:                    classifierToken = findStatement(classifierToken);
0437:                    if (classifierToken == null) {
0438:                        return null;
0439:                    }
0440:
0441:                    switch (classifierToken.getTokenID().getNumericID()) {
0442:                    case CCTokenContext.LBRACE_ID:
0443:                        if (--braceDepth < 0) {
0444:                            return null; // no corresponding right brace
0445:                        }
0446:                        if (braceDepth == 0) {
0447:                            while ((classifierToken = classifierToken
0448:                                    .getPrevious()) != null) {
0449:                                switch (classifierToken.getTokenID()
0450:                                        .getNumericID()) {
0451:                                case CCTokenContext.CLASS_ID:
0452:                                case CCTokenContext.STRUCT_ID:
0453:                                case CCTokenContext.ENUM_ID:
0454:                                case CCTokenContext.UNION_ID:
0455:                                    return classifierToken;
0456:                                }
0457:                            }
0458:                            return null;
0459:                        }
0460:                        break;
0461:
0462:                    case CCTokenContext.RBRACE_ID:
0463:                        braceDepth++;
0464:                        break;
0465:
0466:                    }
0467:                }
0468:            }
0469:
0470:            /** Find the 'try' when the 'catch' is provided.
0471:             * @param catchToken the token with the 'catch' command
0472:             *  for which the 'try' is being searched.
0473:             * @return corresponding 'try' token or null if there's
0474:             *  no corresponding 'try' statement.
0475:             */
0476:            public TokenItem findTry(TokenItem catchToken) {
0477:                if (catchToken == null
0478:                        || (!tokenEquals(catchToken, CCTokenContext.CATCH,
0479:                                tokenContextPath))) {
0480:                    throw new IllegalArgumentException(NbBundle.getBundle(
0481:                            CCFormatSupport.class).getString(
0482:                            "MSG_AcceptOnlyCatch")); //NOI18N
0483:                }
0484:
0485:                int braceDepth = 0; // depth of the braces
0486:                while (true) {
0487:                    catchToken = findStatement(catchToken);
0488:                    if (catchToken == null) {
0489:                        return null;
0490:                    }
0491:
0492:                    switch (catchToken.getTokenID().getNumericID()) {
0493:                    case CCTokenContext.LBRACE_ID:
0494:                        if (--braceDepth < 0) {
0495:                            return null; // no corresponding right brace
0496:                        }
0497:                        break;
0498:
0499:                    case CCTokenContext.RBRACE_ID:
0500:                        braceDepth++;
0501:                        break;
0502:
0503:                    case CCTokenContext.TRY_ID:
0504:                        if (braceDepth == 0) {
0505:                            return catchToken;
0506:                        }
0507:                        break;
0508:                    }
0509:                }
0510:            }
0511:
0512:            /** Find the start of the statement.
0513:             * @param token token from which to start. It searches
0514:             *  backward using <code>findStatement()</code> so it ignores
0515:             *  the given token.
0516:             * @return the statement start token (outer statement start for nested
0517:             *  statements).
0518:             *  It returns the same token if there is '{' before
0519:             *  the given token.
0520:             */
0521:            public TokenItem findStatementStart(TokenItem token) {
0522:                TokenItem t = findStatementStart(token, true);
0523:                // preprocessor tokens are not important (bug#22570)
0524:                while (t != null && isPreprocessorLine(t)) {
0525:                    TokenItem current = t.getPrevious();
0526:                    if (current == null) {
0527:                        return null;
0528:                    }
0529:                    t = findStatementStart(current, true);
0530:                }
0531:                return t;
0532:            }
0533:
0534:            public TokenItem findStatementStart(TokenItem token,
0535:                    boolean outermost) {
0536:                TokenItem t = findStatement(token);
0537:                if (t != null) {
0538:                    switch (t.getTokenID().getNumericID()) {
0539:                    case CCTokenContext.SEMICOLON_ID: // ';' found
0540:                        TokenItem scss = findStatement(t);
0541:                        if (scss == null) {
0542:                            return token;
0543:                        }
0544:                        switch (scss.getTokenID().getNumericID()) {
0545:                        case CCTokenContext.LBRACE_ID: // '{' then ';'
0546:                        case CCTokenContext.RBRACE_ID: // '}' then ';'
0547:                        case CCTokenContext.COLON_ID: // ':' then ';'
0548:                        case CCTokenContext.CASE_ID: // 'case' then ';'
0549:                        case CCTokenContext.DEFAULT_ID:
0550:                        case CCTokenContext.SEMICOLON_ID: // ';' then ';'
0551:                            return t; // return ';'
0552:
0553:                        case CCTokenContext.PRIVATE_ID:
0554:                        case CCTokenContext.PROTECTED_ID:
0555:                        case CCTokenContext.PUBLIC_ID:
0556:
0557:                        case CCTokenContext.DO_ID:
0558:                        case CCTokenContext.FOR_ID:
0559:                        case CCTokenContext.IF_ID:
0560:                        case CCTokenContext.WHILE_ID:
0561:                            return findStatementStart(t, outermost);
0562:
0563:                        case CCTokenContext.ELSE_ID: // 'else' then ';'
0564:                            // Find the corresponding 'if'
0565:                            TokenItem ifss = findIf(scss);
0566:                            if (ifss != null) { // 'if' ... 'else' then ';'
0567:                                return findStatementStart(ifss, outermost);
0568:                            } else { // no valid starting 'if'
0569:                                return scss; // return 'else'
0570:                            }
0571:
0572:                        default: // something usual then ';'
0573:                            TokenItem bscss = findStatement(scss);
0574:                            if (bscss != null) {
0575:                                switch (bscss.getTokenID().getNumericID()) {
0576:                                case CCTokenContext.SEMICOLON_ID: // ';' then stmt ending with ';'
0577:                                case CCTokenContext.LBRACE_ID:
0578:                                case CCTokenContext.RBRACE_ID:
0579:                                case CCTokenContext.COLON_ID:
0580:                                    return scss; // 
0581:
0582:                                case CCTokenContext.DO_ID:
0583:                                case CCTokenContext.FOR_ID:
0584:                                case CCTokenContext.IF_ID:
0585:                                case CCTokenContext.WHILE_ID:
0586:                                    return findStatementStart(bscss, outermost);
0587:
0588:                                case CCTokenContext.ELSE_ID:
0589:                                    // Find the corresponding 'if'
0590:                                    ifss = findIf(bscss);
0591:                                    if (ifss != null) { // 'if' ... 'else' ... ';'
0592:                                        return findStatementStart(ifss,
0593:                                                outermost);
0594:                                    } else { // no valid starting 'if'
0595:                                        return bscss; // return 'else'
0596:                                    }
0597:                                }
0598:                            }
0599:
0600:                            return scss;
0601:                        } // semicolon servicing end
0602:
0603:                    case CCTokenContext.LBRACE_ID: // '{' found
0604:                        return token; // return original token
0605:
0606:                    case CCTokenContext.RBRACE_ID: // '}' found
0607:                        TokenItem lb = findMatchingToken(t, null,
0608:                                CCTokenContext.LBRACE, true);
0609:                        if (lb != null) { // valid matching left-brace
0610:                            // Find a stmt-start of the '{'
0611:                            TokenItem lbss = findStatement(lb);
0612:                            if (lbss != null) {
0613:                                switch (lbss.getTokenID().getNumericID()) {
0614:                                case CCTokenContext.ELSE_ID: // 'else {'
0615:                                    // Find the corresponding 'if'
0616:                                    TokenItem ifss = findIf(lbss);
0617:                                    if (ifss != null) { // valid 'if'
0618:                                        return findStatementStart(ifss,
0619:                                                outermost);
0620:                                    } else {
0621:                                        return lbss; // return 'else'
0622:                                    }
0623:
0624:                                case CCTokenContext.CATCH_ID: // 'catch (...) {'
0625:                                    // I'm not sure what to do if this isn't C++...
0626:                                    // Find the corresponding 'try'
0627:                                    TokenItem tryss = findTry(lbss);
0628:                                    if (tryss != null) { // valid 'try'
0629:                                        return findStatementStart(tryss,
0630:                                                outermost);
0631:                                    } else {
0632:                                        return lbss; // return 'catch'
0633:                                    }
0634:
0635:                                case CCTokenContext.DO_ID:
0636:                                case CCTokenContext.FOR_ID:
0637:                                case CCTokenContext.IF_ID:
0638:                                case CCTokenContext.WHILE_ID:
0639:                                    return findStatementStart(lbss, outermost);
0640:                                }
0641:                                // I copied the next if from JavaFormatSupport. But I'm not 100% certain it
0642:                                // applies...
0643:                                if (lbss.getTokenID().getNumericID() == CCTokenContext.LBRACE_ID) {
0644:                                    return t; // return right brace
0645:                                }
0646:                                return lbss;
0647:                            }
0648:                        }
0649:                        return t; // return right brace
0650:
0651:                    case CCTokenContext.COLON_ID:
0652:                    case CCTokenContext.CASE_ID:
0653:                    case CCTokenContext.DEFAULT_ID:
0654:                        return token;
0655:
0656:                    case CCTokenContext.ELSE_ID:
0657:                        // Find the corresponding 'if'
0658:                        TokenItem ifss = findIf(t);
0659:                        return (ifss != null) ? findStatementStart(ifss,
0660:                                outermost) : t;
0661:
0662:                    case CCTokenContext.DO_ID:
0663:                    case CCTokenContext.FOR_ID:
0664:                    case CCTokenContext.IF_ID:
0665:                    case CCTokenContext.WHILE_ID:
0666:                        if (!outermost) {
0667:                            return t;
0668:                        } else {
0669:                            return findStatementStart(t, outermost);
0670:                        }
0671:
0672:                    case CCTokenContext.IDENTIFIER_ID:
0673:                        return t;
0674:                    default:
0675:                        return t;
0676:                    }
0677:                }
0678:                return token; // return original token
0679:            }
0680:
0681:            /** 
0682:             * Get the indentation for the given token. It first searches whether there's an 
0683:             * non-whitespace and a non-leftbrace character on the line with the token and if so,
0684:             * it takes indent of the non-ws char instead.
0685:             *
0686:             * @param token token for which the indent is being searched.
0687:             *  The token itself is ignored and the previous token is used as a base for the search.
0688:             * @param forceFirstNonWhitespace set true to ignore leftbrace and search 
0689:             *  directly for first non-whitespace
0690:             */
0691:            public int getTokenIndent(TokenItem token,
0692:                    boolean forceFirstNonWhitespace) {
0693:                FormatTokenPosition tp = getPosition(token, 0);
0694:                // this is fix for bugs: 7980 and 9111
0695:                // see the findLineFirstNonWhitespaceAndNonLeftBrace definition
0696:                // for more info about the fix
0697:                FormatTokenPosition fnw;
0698:                if (forceFirstNonWhitespace)
0699:                    fnw = findLineFirstNonWhitespace(tp);
0700:                else
0701:                    fnw = findLineFirstNonWhitespaceAndNonLeftBrace(tp);
0702:
0703:                if (fnw != null) { // valid first non-whitespace
0704:                    tp = fnw;
0705:                }
0706:                return getVisualColumnOffset(tp);
0707:            }
0708:
0709:            public int getTokenIndent(TokenItem token) {
0710:                return getTokenIndent(token, false);
0711:            }
0712:
0713:            /**
0714:             * Find the indentation for the first token on the line.
0715:             * The given token is also examined in some cases.
0716:             */
0717:            public int findIndent(TokenItem token) {
0718:                int indent = -1; // assign invalid indent
0719:
0720:                // First check the given token
0721:                if (token != null) {
0722:                    switch (token.getTokenID().getNumericID()) {
0723:                    case CCTokenContext.ELSE_ID:
0724:                        TokenItem ifss = findIf(token);
0725:                        if (ifss != null) {
0726:                            indent = getTokenIndent(ifss);
0727:                        }
0728:                        break;
0729:
0730:                    case CCTokenContext.LBRACE_ID:
0731:                        TokenItem stmt = findStatement(token);
0732:                        if (stmt == null) {
0733:                            indent = 0;
0734:                        } else {
0735:                            switch (stmt.getTokenID().getNumericID()) {
0736:                            case CCTokenContext.DO_ID:
0737:                            case CCTokenContext.FOR_ID:
0738:                            case CCTokenContext.IF_ID:
0739:                            case CCTokenContext.WHILE_ID:
0740:                            case CCTokenContext.ELSE_ID:
0741:                                indent = getTokenIndent(stmt);
0742:                                break;
0743:
0744:                            case CCTokenContext.LBRACE_ID:
0745:                                indent = getTokenIndent(stmt) + getShiftWidth();
0746:                                break;
0747:
0748:                            default:
0749:                                stmt = findStatementStart(token);
0750:                                if (stmt == null) {
0751:                                    indent = 0;
0752:                                } else if (stmt == token) {
0753:                                    stmt = findStatement(token); // search for delimiter
0754:                                    indent = (stmt != null) ? indent = getTokenIndent(stmt)
0755:                                            : 0;
0756:                                } else { // valid statement
0757:                                    indent = getTokenIndent(stmt);
0758:                                    switch (stmt.getTokenID().getNumericID()) {
0759:                                    case CCTokenContext.LBRACE_ID:
0760:                                        indent += getShiftWidth();
0761:                                        break;
0762:                                    }
0763:                                }
0764:                            }
0765:                        }
0766:                        break;
0767:
0768:                    case CCTokenContext.RBRACE_ID:
0769:                        TokenItem rbmt = findMatchingToken(token, null,
0770:                                CCTokenContext.LBRACE, true);
0771:                        if (rbmt != null) { // valid matching left-brace
0772:                            TokenItem t = findStatement(rbmt);
0773:                            boolean forceFirstNonWhitespace = false;
0774:                            if (t == null) {
0775:                                t = rbmt; // will get indent of the matching brace
0776:                            } else {
0777:                                switch (t.getTokenID().getNumericID()) {
0778:                                case CCTokenContext.SEMICOLON_ID:
0779:                                case CCTokenContext.LBRACE_ID:
0780:                                case CCTokenContext.RBRACE_ID: {
0781:                                    t = rbmt;
0782:                                    forceFirstNonWhitespace = true;
0783:                                }
0784:                                }
0785:                            }
0786:                            // the right brace must be indented to the first
0787:                            // non-whitespace char - forceFirstNonWhitespace=true
0788:                            indent = getTokenIndent(t, forceFirstNonWhitespace);
0789:                        } else { // no matching left brace
0790:                            indent = getTokenIndent(token); // leave as is
0791:                        }
0792:                        break;
0793:
0794:                    case CCTokenContext.CASE_ID:
0795:                    case CCTokenContext.DEFAULT_ID:
0796:                        TokenItem swss = findSwitch(token);
0797:                        if (swss != null) {
0798:                            indent = getTokenIndent(swss);
0799:                            if (indentCasesFromSwitch()) {
0800:                                indent += getShiftWidth();
0801:                            }
0802:                        }
0803:                        break;
0804:                    case CCTokenContext.PUBLIC_ID:
0805:                    case CCTokenContext.PRIVATE_ID:
0806:                    case CCTokenContext.PROTECTED_ID:
0807:                        TokenItem cls = findClassifier(token);
0808:                        if (cls != null) {
0809:                            indent = getTokenIndent(cls);
0810:                        }
0811:                        break;
0812:                    case CCTokenContext.CLASS_ID:
0813:                    case CCTokenContext.STRUCT_ID:
0814:                        TokenItem clsTemplate = findClassifierStart(token);
0815:                        if (clsTemplate != null) {
0816:                            indent = getTokenIndent(clsTemplate);
0817:                        }
0818:                        break;
0819:                    }
0820:                }
0821:
0822:                // If indent not found, search back for the first important token
0823:                if (indent < 0) { // if not yet resolved
0824:                    TokenItem t = findImportantToken(token, null, true, true);
0825:                    if (t != null) { // valid important token
0826:                        switch (t.getTokenID().getNumericID()) {
0827:                        case CCTokenContext.SEMICOLON_ID: // semicolon found
0828:                            TokenItem tt = findStatementStart(token);
0829:                            // preprocessor tokens are not important (bug#22570)
0830:                            while (tt != null
0831:                                    && (isPreprocessorLine(tt) || tt.getImage()
0832:                                            .startsWith("\n"))) { // NOI18N
0833:                                tt = findStatementStart(tt.getPrevious());
0834:                            }
0835:                            if (tt != null) {
0836:                                switch (tt.getTokenID().getNumericID()) {
0837:                                case CCTokenContext.PUBLIC_ID:
0838:                                case CCTokenContext.PRIVATE_ID:
0839:                                case CCTokenContext.PROTECTED_ID:
0840:                                    indent = getTokenIndent(tt)
0841:                                            + getShiftWidth();
0842:                                    break;
0843:                                default:
0844:                                    indent = getTokenIndent(tt);
0845:                                    break;
0846:                                }
0847:                            } else {
0848:                                indent = getTokenIndent(tt);
0849:                            }
0850:                            break;
0851:
0852:                        case CCTokenContext.LBRACE_ID:
0853:                            TokenItem lbss = findStatementStart(t, false);
0854:                            if (lbss == null) {
0855:                                lbss = t;
0856:                            }
0857:                            indent = getTokenIndent(lbss) + getShiftWidth();
0858:                            break;
0859:
0860:                        case CCTokenContext.RBRACE_ID:
0861:                            TokenItem t3 = findStatementStart(token);
0862:                            indent = getTokenIndent(t3);
0863:                            break;
0864:
0865:                        case CCTokenContext.COLON_ID:
0866:                            TokenItem ttt = getVisibility(t);
0867:                            if (ttt != null) {
0868:                                indent = getTokenIndent(ttt) + getShiftWidth();
0869:                            } else {
0870:                                ttt = findAnyToken(t, null, new TokenID[] {
0871:                                        CCTokenContext.CASE,
0872:                                        CCTokenContext.DEFAULT,
0873:                                        CCTokenContext.QUESTION,
0874:                                        CCTokenContext.PRIVATE,
0875:                                        CCTokenContext.PROTECTED,
0876:                                        CCTokenContext.PUBLIC }, t
0877:                                        .getTokenContextPath(), true);
0878:                                if (ttt != null) {
0879:                                    int id = ttt.getTokenID().getNumericID();
0880:                                    if (id == CCTokenContext.QUESTION_ID) {
0881:                                        indent = getTokenIndent(ttt)
0882:                                                + getShiftWidth();
0883:                                    } else if (id == CCTokenContext.CASE_ID
0884:                                            || id == CCTokenContext.DEFAULT_ID) {
0885:                                        indent = getTokenIndent(ttt)
0886:                                                + getShiftWidth();
0887:                                    } else {
0888:                                        indent = getTokenIndent(t);// + getShiftWidth();
0889:                                    }
0890:                                } else {
0891:                                    // Indent of line with ':' plus one indent level
0892:                                    indent = getTokenIndent(t);// + getShiftWidth();
0893:                                }
0894:                            }
0895:                            break;
0896:
0897:                        case CCTokenContext.QUESTION_ID:
0898:                        case CCTokenContext.DO_ID:
0899:                        case CCTokenContext.ELSE_ID:
0900:                            indent = getTokenIndent(t) + getShiftWidth();
0901:                            break;
0902:
0903:                        case CCTokenContext.RPAREN_ID:
0904:                            // Try to find the matching left paren
0905:                            TokenItem rpmt = findMatchingToken(t, null,
0906:                                    CCTokenContext.LPAREN, true);
0907:                            if (rpmt != null) {
0908:                                rpmt = findImportantToken(rpmt, null, true,
0909:                                        true);
0910:                                // Check whether there are the indent changing kwds
0911:                                if (rpmt != null
0912:                                        && rpmt.getTokenContextPath() == tokenContextPath) {
0913:                                    switch (rpmt.getTokenID().getNumericID()) {
0914:                                    case CCTokenContext.FOR_ID:
0915:                                    case CCTokenContext.IF_ID:
0916:                                    case CCTokenContext.WHILE_ID:
0917:                                        // Indent one level
0918:                                        indent = getTokenIndent(rpmt)
0919:                                                + getShiftWidth();
0920:                                        break;
0921:                                    }
0922:                                }
0923:                            }
0924:                            if (indent < 0) {
0925:                                indent = computeStatementIndent(t);
0926:                            }
0927:                            break;
0928:
0929:                        case CCTokenContext.COMMA_ID:
0930:                            if (isEnumComma(t)) {
0931:                                indent = getTokenIndent(t);
0932:                                break;
0933:                            } // else continue to default
0934:
0935:                        default:
0936:                            indent = computeStatementIndent(t);
0937:                            break;
0938:                        }
0939:
0940:                        if (indent < 0) { // no indent found yet
0941:                            indent = getTokenIndent(t);
0942:                        }
0943:                    }
0944:                }
0945:
0946:                if (indent < 0) { // no important token found
0947:                    indent = 0;
0948:                }
0949:                return indent;
0950:            }
0951:
0952:            private int computeStatementIndent(final TokenItem t) {
0953:                int indent;
0954:                // Find stmt start and add continuation indent
0955:                TokenItem stmtStart = findStatementStart(t);
0956:                indent = getTokenIndent(stmtStart);
0957:                //int tindent = getTokenIndent(t);
0958:                //if (tindent > indent)
0959:                //    return tindent;
0960:
0961:                if (stmtStart != null) {
0962:                    // Check whether there is a comma on the previous line end
0963:                    // and if so then also check whether the present
0964:                    // statement is inside array initialization statement
0965:                    // and not inside parents and if so then do not indent
0966:                    // statement continuation
0967:                    if (t != null
0968:                            && tokenEquals(t, CCTokenContext.COMMA,
0969:                                    tokenContextPath)) {
0970:                        if (isArrayInitializationBraceBlock(t, null)
0971:                                && getLeftParen(t, stmtStart) == null) {
0972:                            return indent;
0973:                        }
0974:                        TokenItem lparen = getLeftParen(t, stmtStart);
0975:                        if (lparen != null) {
0976:                            TokenItem prev = findImportantToken(lparen, null,
0977:                                    true, true);
0978:                            if (prev != null
0979:                                    && prev.getTokenID().getNumericID() == CCTokenContext.IDENTIFIER_ID) {
0980:                                if (isStatement(stmtStart)) {
0981:                                    if (alignMultilineCallArgs()) {
0982:                                        return getVisualColumnOffset(getPosition(
0983:                                                lparen, 0)) + 1;
0984:                                    }
0985:                                } else {
0986:                                    if (alignMultilineMethodParams()) {
0987:                                        return getVisualColumnOffset(getPosition(
0988:                                                lparen, 0)) + 1;
0989:                                    }
0990:                                }
0991:                            }
0992:                        }
0993:                    } else if (!isStatement(stmtStart)) {
0994:                        return indent;
0995:                    }
0996:                    indent += getFormatStatementContinuationIndent();
0997:                }
0998:                return indent;
0999:            }
1000:
1001:            private boolean isStatement(TokenItem t) {
1002:                boolean likeDeclaration = false;
1003:                boolean findLParen = false;
1004:                boolean findQuestion = false;
1005:                int identifiers = 0;
1006:                while (t != null) {
1007:                    if (t.getTokenContextPath() == tokenContextPath) {
1008:                        switch (t.getTokenID().getNumericID()) {
1009:                        case CCTokenContext.EQ_ID:
1010:                        case CCTokenContext.AND_EQ_ID:
1011:                        case CCTokenContext.OR_EQ_ID:
1012:                        case CCTokenContext.MUL_EQ_ID:
1013:                        case CCTokenContext.DIV_EQ_ID:
1014:                        case CCTokenContext.XOR_EQ_ID:
1015:                        case CCTokenContext.MOD_EQ_ID:
1016:                        case CCTokenContext.DELETE_ID:
1017:                        case CCTokenContext.RETURN_ID:
1018:                        case CCTokenContext.BREAK_ID:
1019:                        case CCTokenContext.CASE_ID:
1020:                        case CCTokenContext.CATCH_ID:
1021:                        case CCTokenContext.CONTINUE_ID:
1022:                        case CCTokenContext.DEFAULT_ID:
1023:                        case CCTokenContext.DO_ID:
1024:                        case CCTokenContext.ELSE_ID:
1025:                        case CCTokenContext.FOR_ID:
1026:                        case CCTokenContext.GOTO_ID:
1027:                        case CCTokenContext.IF_ID:
1028:                        case CCTokenContext.SIZEOF_ID:
1029:                        case CCTokenContext.SWITCH_ID:
1030:                        case CCTokenContext.THIS_ID:
1031:                        case CCTokenContext.THROW_ID:
1032:                        case CCTokenContext.TRY_ID:
1033:                        case CCTokenContext.USING_ID:
1034:                        case CCTokenContext.WHILE_ID:
1035:                            return true;
1036:                        case CCTokenContext.SEMICOLON_ID:
1037:                            if (likeDeclaration) {
1038:                                return false;
1039:                            }
1040:                            return true;
1041:                        case CCTokenContext.FRIEND_ID:
1042:                        case CCTokenContext.EXPLICIT_ID:
1043:                        case CCTokenContext.EXTERN_ID:
1044:                        case CCTokenContext.CLASS_ID:
1045:                        case CCTokenContext.STATIC_ID:
1046:                        case CCTokenContext.OPERATOR_ID:
1047:                        case CCTokenContext.PRIVATE_ID:
1048:                        case CCTokenContext.PROTECTED_ID:
1049:                        case CCTokenContext.PUBLIC_ID:
1050:                        case CCTokenContext.NAMESPACE_ID:
1051:                        case CCTokenContext.TEMPLATE_ID:
1052:                        case CCTokenContext.UNION_ID:
1053:                        case CCTokenContext.ENUM_ID:
1054:                        case CCTokenContext.VIRTUAL_ID:
1055:                        case CCTokenContext.INLINE_ID:
1056:                        case CCTokenContext.LBRACE_ID:
1057:                            return false;
1058:                        case CCTokenContext.COLON_ID:
1059:                            if (!findQuestion) {
1060:                                return false;
1061:                            }
1062:                            break;
1063:                        case CCTokenContext.QUESTION_ID:
1064:                            findQuestion = true;
1065:                            break;
1066:                        case CCTokenContext.SCOPE_ID:
1067:                            if (!findLParen && identifiers == 1) {
1068:                                likeDeclaration = true;
1069:                            }
1070:                            break;
1071:                        case CCTokenContext.RPAREN_ID:
1072:                            break;
1073:                        case CCTokenContext.LPAREN_ID:
1074:                            if (!findLParen && identifiers > 1) {
1075:                                likeDeclaration = true;
1076:                            }
1077:                            findLParen = true;
1078:                            break;
1079:                        case CCTokenContext.ASM_ID:
1080:                        case CCTokenContext.AUTO_ID:
1081:                        case CCTokenContext.BOOLEAN_ID:
1082:                        case CCTokenContext.CHAR_ID:
1083:                        case CCTokenContext.DOUBLE_ID:
1084:                        case CCTokenContext.EXPORT_ID:
1085:                        case CCTokenContext.FLOAT_ID:
1086:                        case CCTokenContext.INT_ID:
1087:                        case CCTokenContext.LONG_ID:
1088:                        case CCTokenContext.MUTABLE_ID:
1089:                        case CCTokenContext.REGISTER_ID:
1090:                        case CCTokenContext.SHORT_ID:
1091:                        case CCTokenContext.SIGNED_ID:
1092:                        case CCTokenContext.STRUCT_ID:
1093:                        case CCTokenContext.TYPEDEF_ID:
1094:                        case CCTokenContext.TYPENAME_ID:
1095:                        case CCTokenContext.UNSIGNED_ID:
1096:                        case CCTokenContext.VOID_ID:
1097:                        case CCTokenContext.WCHAR_T_ID:
1098:                        case CCTokenContext.VOLATILE_ID:
1099:                        case CCTokenContext.CONST_ID:
1100:                            if (!findLParen) {
1101:                                return false;
1102:                            }
1103:                            break;
1104:                        case CCTokenContext.IDENTIFIER_ID:
1105:                            identifiers++;
1106:                            break;
1107:                        }
1108:                    }
1109:                    t = t.getNext();
1110:                }
1111:                return true;
1112:            }
1113:
1114:            public FormatTokenPosition indentLine(FormatTokenPosition pos) {
1115:                int indent = 0; // Desired indent
1116:
1117:                // Get the first non-whitespace position on the line
1118:                FormatTokenPosition firstNWS = findLineFirstNonWhitespace(pos);
1119:                if (firstNWS != null) { // some non-WS on the line
1120:                    if (isPreprocessorLine(firstNWS.getToken())) {
1121:                        // leave untouched for now, (bug#22570)
1122:                        if (!isPreprocessorAtLineStart(firstNWS.getToken())) {
1123:                            return pos;
1124:                        }
1125:                    } else if (isComment(firstNWS)) { // comment is first on the line
1126:                        if (isMultiLineComment(firstNWS)
1127:                                && firstNWS.getOffset() != 0) {
1128:
1129:                            // Indent the inner lines of the multi-line comment by one
1130:                            indent = getLineIndent(getPosition(firstNWS
1131:                                    .getToken(), 0), true) + 1;
1132:
1133:                            // If the line is inside multi-line comment and doesn't contain '*'
1134:                            if (!isIndentOnly()) {
1135:                                if (getChar(firstNWS) != '*') {
1136:                                    if (isCCDocComment(firstNWS.getToken())) {
1137:                                        if (getFormatLeadingStarInComment()) {
1138:                                            insertString(firstNWS, "* "); // NOI18N
1139:                                        }
1140:                                    } else {
1141:                                        // For non-java-doc not because it can be commented code
1142:                                        indent = getLineIndent(pos, true);
1143:                                    }
1144:                                }
1145:                            } else {
1146:                                if (getChar(firstNWS) != '*') { // e.g. not for '*/'
1147:                                    if (isCCDocComment(firstNWS.getToken())) {
1148:                                        if (getFormatLeadingStarInComment()) {
1149:                                            insertString(firstNWS, "* "); // NOI18N
1150:                                            setIndentShift(2);
1151:                                        }
1152:                                    }
1153:                                }
1154:                            }
1155:                        } else if (!isMultiLineComment(firstNWS)) { // line-comment
1156:                            indent = firstNWS.equals(findLineStart(firstNWS)) ? getLineIndent(
1157:                                    firstNWS, true)
1158:                                    : findIndent(firstNWS.getToken());
1159:                        } else { // multi-line comment
1160:                            if (isCCDocComment(firstNWS.getToken())) {
1161:                                indent = findIndent(firstNWS.getToken());
1162:                            } else {
1163:                                // check whether the multiline comment isn't finished on the same line (see issue 12821)
1164:                                if (firstNWS.getToken().getImage()
1165:                                        .indexOf('\n') == -1) {
1166:                                    indent = findIndent(firstNWS.getToken());
1167:                                } else {
1168:                                    indent = getLineIndent(firstNWS, true);
1169:                                }
1170:                            }
1171:                        }
1172:                    } else { // first non-WS char is not comment
1173:                        indent = findIndent(firstNWS.getToken());
1174:                    }
1175:                } else { // whole line is WS
1176:                    // Can be empty line inside multi-line comment
1177:                    TokenItem token = pos.getToken();
1178:                    if (token == null) {
1179:                        token = findLineStart(pos).getToken();
1180:                        if (token == null) { // empty line
1181:                            token = getLastToken();
1182:                        }
1183:                    }
1184:
1185:                    if (token != null && isMultiLineComment(token)) {
1186:                        if (getFormatLeadingStarInComment()
1187:                                && (isIndentOnly() || isCCDocComment(token))) {
1188:                            // Insert initial '*'
1189:                            insertString(pos, "*"); // NOI18N
1190:                            setIndentShift(1);
1191:                        }
1192:
1193:                        // Indent the multi-comment
1194:                        indent = getVisualColumnOffset(getPosition(token, 0)) + 1;
1195:                    } else { // non-multi-line comment
1196:                        indent = findIndent(pos.getToken());
1197:                    }
1198:                }
1199:
1200:                // For indent-only always indent
1201:                return changeLineIndent(pos, indent);
1202:            }
1203:
1204:            /** 
1205:             * Check whether the given semicolon is inside the for() statement
1206:             *
1207:             * @param token token to check. It must be a semicolon
1208:             * @return true if the given semicolon is inside the for() statement, or false otherwise
1209:             */
1210:            public boolean isForLoopSemicolon(TokenItem token) {
1211:                if (token == null
1212:                        || !tokenEquals(token, CCTokenContext.SEMICOLON,
1213:                                tokenContextPath)) {
1214:                    throw new IllegalArgumentException("Only accept ';'."); // NOI18N
1215:                }
1216:
1217:                int parDepth = 0; // parenthesis depth
1218:                int braceDepth = 0; // brace depth
1219:                boolean semicolonFound = false; // next semicolon
1220:                token = token.getPrevious(); // ignore this semicolon
1221:                while (token != null) {
1222:                    if (tokenEquals(token, CCTokenContext.LPAREN,
1223:                            tokenContextPath)) {
1224:                        if (parDepth == 0) { // could be a 'for ('
1225:                            FormatTokenPosition tp = getPosition(token, 0);
1226:                            tp = findImportant(tp, null, false, true);
1227:                            if (tp != null
1228:                                    && tokenEquals(tp.getToken(),
1229:                                            CCTokenContext.FOR,
1230:                                            tokenContextPath)) {
1231:                                return true;
1232:                            }
1233:                            return false;
1234:                        } else { // non-zero depth
1235:                            parDepth--;
1236:                        }
1237:                    } else if (tokenEquals(token, CCTokenContext.RPAREN,
1238:                            tokenContextPath)) {
1239:                        parDepth++;
1240:                    } else if (tokenEquals(token, CCTokenContext.LBRACE,
1241:                            tokenContextPath)) {
1242:                        if (braceDepth == 0) { // unclosed left brace
1243:                            return false;
1244:                        }
1245:                        braceDepth--;
1246:                    } else if (tokenEquals(token, CCTokenContext.RBRACE,
1247:                            tokenContextPath)) {
1248:                        braceDepth++;
1249:                    } else if (tokenEquals(token, CCTokenContext.SEMICOLON,
1250:                            tokenContextPath)) {
1251:                        if (semicolonFound) { // one semicolon already found
1252:                            return false;
1253:                        }
1254:                        semicolonFound = true;
1255:                    }
1256:
1257:                    token = token.getPrevious();
1258:                }
1259:
1260:                return false;
1261:            }
1262:
1263:            private TokenItem findClassifierStart(TokenItem token) {
1264:                while (true) {
1265:                    token = findStatement(token);
1266:                    if (token == null) {
1267:                        return null;
1268:                    }
1269:                    switch (token.getTokenID().getNumericID()) {
1270:                    case CCTokenContext.LBRACE_ID:
1271:                    case CCTokenContext.RBRACE_ID:
1272:                    case CCTokenContext.SEMICOLON_ID:
1273:                        return null;
1274:                    case CCTokenContext.TEMPLATE_ID:
1275:                        return findStatementStart(token);
1276:                    }
1277:                }
1278:            }
1279:
1280:            private TokenItem getVisibility(TokenItem token) {
1281:                TokenItem t = token;
1282:                if (t != null) {
1283:                    t = token.getPrevious();
1284:                }
1285:                while (t != null) {
1286:                    if (t.getTokenContextPath() == tokenContextPath) {
1287:                        switch (t.getTokenID().getNumericID()) {
1288:                        case CCTokenContext.SEMICOLON_ID:
1289:                        case CCTokenContext.LBRACE_ID:
1290:                        case CCTokenContext.RBRACE_ID:
1291:                            return null;
1292:                        case CCTokenContext.PRIVATE_ID:
1293:                        case CCTokenContext.PROTECTED_ID:
1294:                        case CCTokenContext.PUBLIC_ID:
1295:                            return t;
1296:                        }
1297:                    }
1298:                    t = t.getPrevious();
1299:                }
1300:                return null;
1301:            }
1302:
1303:            /**
1304:             * Check whether there are left parenthesis before the given token
1305:             * until the limit token.
1306:             * 
1307:             * @param token non-null token from which to start searching back.
1308:             * @param limitToken limit token when reached the search will stop
1309:             *  with returning false.
1310:             * @return true if there is LPAREN token before the given token
1311:             *  (while respecting paren nesting).
1312:             */
1313:            private TokenItem getLeftParen(TokenItem token, TokenItem limitToken) {
1314:                int depth = 0;
1315:                token = token.getPrevious();
1316:
1317:                while (token != null && token != limitToken) {
1318:                    if (tokenEquals(token, CCTokenContext.LPAREN,
1319:                            tokenContextPath)) {
1320:                        if (--depth < 0) {
1321:                            return token;
1322:                        }
1323:
1324:                    } else if (tokenEquals(token, CCTokenContext.RPAREN,
1325:                            tokenContextPath)) {
1326:                        depth++;
1327:                    }
1328:                    token = token.getPrevious();
1329:                }
1330:                return null;
1331:            }
1332:
1333:            /**
1334:             * Check whether the given token is located in array initialization block.
1335:             * 
1336:             * @param token non-null token from which to start searching back.
1337:             * @param limitToken limit token when reached the search will stop
1338:             *  with returning false.
1339:             * @return true if the token is located inside the brace block of array
1340:             *  initialization.
1341:             */
1342:            private boolean isArrayInitializationBraceBlock(TokenItem token,
1343:                    TokenItem limitToken) {
1344:                int depth = 0;
1345:                token = token.getPrevious();
1346:
1347:                while (token != null && token != limitToken
1348:                        && token.getTokenContextPath() == tokenContextPath) {
1349:                    switch (token.getTokenID().getNumericID()) {
1350:                    case CCTokenContext.RBRACE_ID:
1351:                        depth++;
1352:                        break;
1353:
1354:                    case CCTokenContext.LBRACE_ID:
1355:                        depth--;
1356:                        if (depth < 0) {
1357:                            TokenItem prev = findImportantToken(token,
1358:                                    limitToken, true, true);
1359:                            // Array initialization left brace should be preceded
1360:                            // by either '=' or ']' i.e.
1361:                            // either "String array = { "a", "b", ... }"
1362:                            // or     "String array = new String[] { "a", "b", ... }"
1363:                            return (prev != null
1364:                                    && prev.getTokenContextPath() == tokenContextPath && (CCTokenContext.RBRACKET
1365:                                    .equals(prev.getTokenID()) || CCTokenContext.EQ
1366:                                    .equals(prev.getTokenID())));
1367:                        }
1368:                        break;
1369:
1370:                    // Array initialization block should not contain statements or ';'
1371:                    case CCTokenContext.DO_ID:
1372:                    case CCTokenContext.FOR_ID:
1373:                    case CCTokenContext.IF_ID:
1374:                    case CCTokenContext.WHILE_ID:
1375:                    case CCTokenContext.SEMICOLON_ID:
1376:                        if (depth == 0) {
1377:                            return false;
1378:                        }
1379:                    }
1380:                    token = token.getPrevious();
1381:                }
1382:                return false;
1383:            }
1384:
1385:            public boolean isEnumComma(TokenItem token) {
1386:                while (token != null
1387:                        && tokenEquals(token, CCTokenContext.COMMA,
1388:                                tokenContextPath)) {
1389:                    TokenItem itm = findStatementStart(token);
1390:                    if (itm == token) {
1391:                        break;
1392:                    }
1393:                    token = itm;
1394:                }
1395:                if (token != null
1396:                        && tokenEquals(token, CCTokenContext.IDENTIFIER,
1397:                                tokenContextPath)) {
1398:                    TokenItem itm = findImportantToken(token, null, true, true);
1399:                    if (itm != null
1400:                            && tokenEquals(itm, CCTokenContext.LBRACE,
1401:                                    tokenContextPath)) {
1402:                        TokenItem startItem = findStatementStart(itm);
1403:                        if (startItem != null
1404:                                && findToken(startItem, itm,
1405:                                        CCTokenContext.ENUM, tokenContextPath,
1406:                                        null, false) != null)
1407:                            return true;
1408:                    }
1409:                }
1410:                return false;
1411:            }
1412:
1413:            private CodeStyle getCodeStyle() {
1414:                return CodeStyle.getDefault(language);
1415:            }
1416:
1417:            public boolean getFormatSpaceBeforeMethodCallParenthesis() {
1418:                //return getCodeStyle().getFormatSpaceBeforeParenthesis();
1419:                return getCodeStyle().spaceBeforeMethodCallParen();
1420:            }
1421:
1422:            public boolean getFormatSpaceAfterComma() {
1423:                return getCodeStyle().spaceAfterComma();
1424:            }
1425:
1426:            public boolean indentCasesFromSwitch() {
1427:                return getCodeStyle().indentCasesFromSwitch();
1428:            }
1429:
1430:            public boolean getFormatNewlineBeforeBrace() {
1431:                return getCodeStyle().getFormatNewlineBeforeBrace() == CodeStyle.BracePlacement.NEW_LINE;
1432:            }
1433:
1434:            public boolean getFormatNewlineBeforeBraceDeclaration() {
1435:                return getCodeStyle().getFormatNewlineBeforeBraceDeclaration() == CodeStyle.BracePlacement.NEW_LINE;
1436:            }
1437:
1438:            public boolean getFormatLeadingStarInComment() {
1439:                return getCodeStyle().getFormatLeadingStarInComment();
1440:            }
1441:
1442:            private int getFormatStatementContinuationIndent() {
1443:                return getCodeStyle().getFormatStatementContinuationIndent();
1444:            }
1445:
1446:            private boolean alignMultilineCallArgs() {
1447:                return getCodeStyle().alignMultilineCallArgs();
1448:            }
1449:
1450:            private boolean alignMultilineMethodParams() {
1451:                return getCodeStyle().alignMultilineMethodParams();
1452:            }
1453:
1454:            /*   this is fix for bugs: 7980 and 9111. if user enters
1455:             *        {   foo();
1456:             *   and press enter at the end of the line, she wants
1457:             *   to be indented just under "f" in "foo();" and not under the "{" 
1458:             *   as it happens now. and this is what findLineFirstNonWhitespaceAndNonLeftBrace checks
1459:             */
1460:            public FormatTokenPosition findLineFirstNonWhitespaceAndNonLeftBrace(
1461:                    FormatTokenPosition pos) {
1462:                // first call the findLineFirstNonWhitespace
1463:                FormatTokenPosition ftp = super .findLineFirstNonWhitespace(pos);
1464:                if (ftp == null) { // no line start, no WS
1465:                    return null;
1466:                }
1467:
1468:                // now checks if the first non-whitespace char is "{"
1469:                // if it is, find the next non-whitespace char
1470:                if (!ftp.getToken().getImage().startsWith("{")) // NOI18N
1471:                    return ftp;
1472:
1473:                // if the left brace is closed on the same line - "{ foo(); }"
1474:                // it must be ignored. otherwise next statement is incorrectly indented 
1475:                // under the "f" and not under the "{" as expected
1476:                FormatTokenPosition eolp = findNextEOL(ftp);
1477:                TokenItem rbmt = findMatchingToken(ftp.getToken(),
1478:                        eolp != null ? eolp.getToken() : null,
1479:                        CCTokenContext.RBRACE, false);
1480:                if (rbmt != null)
1481:                    return ftp;
1482:
1483:                FormatTokenPosition ftp_next = getNextPosition(ftp);
1484:                if (ftp_next == null)
1485:                    return ftp;
1486:
1487:                FormatTokenPosition ftp2 = findImportant(ftp_next, null, true,
1488:                        false);
1489:                if (ftp2 != null)
1490:                    return ftp2;
1491:                else
1492:                    return ftp;
1493:            }
1494:
1495:            public TokenItem findImportantToken(TokenItem startToken,
1496:                    TokenItem limitToken, boolean backward,
1497:                    boolean ignorePreprocessor) {
1498:                TokenItem t = findImportantToken(startToken, limitToken,
1499:                        backward);
1500:                if (ignorePreprocessor) {
1501:                    // preprocessor tokens are not important (bug#22570)
1502:                    while (t != null && getPosition(t, 0) != null) {
1503:                        FormatTokenPosition ft = findLineFirstNonWhitespace(getPosition(
1504:                                t, 0));
1505:                        if (ft == null) {
1506:                            return null;
1507:                        }
1508:                        if (isPreprocessorLine(ft.getToken())) {
1509:                            t = backward ? t.getPrevious() : t.getNext();
1510:                            if (t != null) {
1511:                                t = findImportantToken(t, limitToken, backward);
1512:                            }
1513:                        } else {
1514:                            break;
1515:                        }
1516:                    }
1517:                }
1518:                return t;
1519:            }
1520:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.