cdt/cdt_6_0_x/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/CIndenter.java
author dadubrow
Thu, 29 Apr 2010 11:30:21 -0500
branchRCL_2_4
changeset 140 6d6cf3bdff43
parent 138 e0657161c0cc
permissions -rw-r--r--
Bug 11179 fix indentation for blocks
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
37
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
     1
/*******************************************************************************
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
     2
 * Copyright (c) 2000, 2009 IBM Corporation and others.
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
     3
 * All rights reserved. This program and the accompanying materials
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
     4
 * are made available under the terms of the Eclipse Public License v1.0
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
     5
 * which accompanies this distribution, and is available at
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
     6
 * http://www.eclipse.org/legal/epl-v10.html
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
     7
 *
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
     8
 * Contributors:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
     9
 *     IBM Corporation - initial API and implementation
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    10
 *     Sergey Prigogin (Google)
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    11
 *     Anton Leherbauer (Wind River Systems)
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    12
 *******************************************************************************/
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    13
package org.eclipse.cdt.internal.ui.text;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    14
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    15
import org.eclipse.core.runtime.Assert;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    16
import org.eclipse.core.runtime.Platform;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    17
import org.eclipse.core.runtime.preferences.IPreferencesService;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    18
import org.eclipse.jface.text.BadLocationException;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    19
import org.eclipse.jface.text.IDocument;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    20
import org.eclipse.jface.text.IRegion;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    21
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    22
import org.eclipse.cdt.core.CCorePlugin;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    23
import org.eclipse.cdt.core.formatter.DefaultCodeFormatterConstants;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    24
import org.eclipse.cdt.core.model.ICProject;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    25
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    26
import org.eclipse.cdt.internal.corext.util.CodeFormatterUtil;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    27
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    28
/**
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    29
 * Uses the {@link org.eclipse.cdt.internal.ui.text.CHeuristicScanner} to
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    30
 * get the indentation level for a certain position in a document.
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    31
 *
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    32
 * <p>
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    33
 * An instance holds some internal position in the document and is therefore
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    34
 * not thread-safe.
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    35
 * </p>
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    36
 */
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    37
public final class CIndenter {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    38
	
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    39
	/**
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    40
	 * The CDT Core preferences.
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    41
	 */
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    42
	private final class CorePrefs {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    43
		final boolean prefUseTabs;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    44
		final int prefTabSize;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    45
		final int prefIndentationSize;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    46
		final boolean prefArrayDimensionsDeepIndent;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    47
		final int prefArrayIndent;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    48
		final boolean prefArrayDeepIndent;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    49
		final boolean prefTernaryDeepAlign;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    50
		final int prefTernaryIndent;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    51
		final int prefCaseIndent;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    52
		final int prefCaseBlockIndent;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    53
		final int prefAssignmentIndent;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    54
		final int prefSimpleIndent;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    55
		final int prefBracketIndent;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    56
		final boolean prefMethodDeclDeepIndent;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    57
		final boolean prefMethodDeclFirstParameterDeepIndent;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    58
		final int prefMethodDeclIndent;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    59
		final boolean prefMethodCallDeepIndent;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    60
		final boolean prefMethodCallFirstParameterDeepIndent;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    61
		final int prefMethodCallIndent;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    62
		final boolean prefParenthesisDeepIndent;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    63
		final int prefParenthesisIndent;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    64
		final int prefBlockIndent;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    65
		final int prefMethodBodyIndent;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    66
		final int prefTypeIndent;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    67
		final int prefAccessSpecifierIndent;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    68
		final int prefAccessSpecifierExtraSpaces;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    69
		final int prefNamespaceBodyIndent;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    70
		final boolean prefIndentBracesForBlocks;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    71
		final boolean prefIndentBracesForArrays;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    72
		final boolean prefIndentBracesForMethods;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    73
		final boolean prefIndentBracesForTypes;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    74
		final int prefContinuationIndent;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    75
		final boolean prefHasTemplates;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    76
		final String prefTabChar;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    77
		
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    78
		private final ICProject fProject;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    79
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    80
		/**
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    81
		 * Returns the possibly project-specific core preference defined under <code>key</code>.
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    82
		 *
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    83
		 * @param key the key of the preference
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    84
		 * @return the value of the preference
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    85
		 */
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    86
		private String getCoreFormatterOption(String key) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    87
			if (fProject == null)
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    88
				return CCorePlugin.getOption(key);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    89
			return fProject.getOption(key, true);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    90
		}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    91
		
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    92
		CorePrefs(ICProject project) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    93
			fProject= project;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    94
			prefUseTabs= prefUseTabs();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    95
			prefTabSize= prefTabSize();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    96
			prefIndentationSize= prefIndentationSize();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    97
			prefArrayDimensionsDeepIndent= prefArrayDimensionsDeepIndent();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    98
			prefContinuationIndent= prefContinuationIndent();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    99
			prefBlockIndent= prefBlockIndent();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   100
			prefArrayIndent= prefArrayIndent();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   101
			prefArrayDeepIndent= prefArrayDeepIndent();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   102
			prefTernaryDeepAlign= prefTernaryDeepAlign();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   103
			prefTernaryIndent= prefTernaryIndent();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   104
			prefCaseIndent= prefCaseIndent();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   105
			prefCaseBlockIndent= prefCaseBlockIndent();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   106
			prefAssignmentIndent= prefAssignmentIndent();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   107
			prefIndentBracesForBlocks= prefIndentBracesForBlocks();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   108
			prefSimpleIndent= prefSimpleIndent();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   109
			prefBracketIndent= prefBracketIndent();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   110
			prefMethodDeclDeepIndent= prefMethodDeclDeepIndent();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   111
			prefMethodDeclFirstParameterDeepIndent= prefMethodDeclFirstParameterDeepIndent();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   112
			prefMethodDeclIndent= prefMethodDeclIndent();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   113
			prefMethodCallDeepIndent= prefMethodCallDeepIndent();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   114
			prefMethodCallFirstParameterDeepIndent= prefMethodCallFirstParameterDeepIndent();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   115
			prefMethodCallIndent= prefMethodCallIndent();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   116
			prefParenthesisDeepIndent= prefParenthesisDeepIndent();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   117
			prefParenthesisIndent= prefParenthesisIndent();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   118
			prefMethodBodyIndent= prefMethodBodyIndent();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   119
			prefTypeIndent= prefTypeIndent();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   120
			prefAccessSpecifierIndent= prefAccessSpecifierIndent();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   121
			prefAccessSpecifierExtraSpaces= prefAccessSpecifierExtraSpaces();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   122
			prefNamespaceBodyIndent= prefNamespaceBodyIndent();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   123
			prefIndentBracesForArrays= prefIndentBracesForArrays();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   124
			prefIndentBracesForMethods= prefIndentBracesForMethods();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   125
			prefIndentBracesForTypes= prefIndentBracesForTypes();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   126
			prefHasTemplates= hasTemplates();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   127
			prefTabChar= getCoreFormatterOption(DefaultCodeFormatterConstants.FORMATTER_TAB_CHAR);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   128
		}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   129
		
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   130
		private boolean prefUseTabs() {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   131
			return !CCorePlugin.SPACE.equals(getCoreFormatterOption(DefaultCodeFormatterConstants.FORMATTER_TAB_CHAR));
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   132
		}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   133
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   134
		private int prefTabSize() {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   135
			return CodeFormatterUtil.getTabWidth(fProject);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   136
		}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   137
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   138
		private int prefIndentationSize() {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   139
			return CodeFormatterUtil.getIndentWidth(fProject);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   140
		}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   141
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   142
		private boolean prefArrayDimensionsDeepIndent() {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   143
			return true; // sensible default, no formatter setting
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   144
		}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   145
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   146
		private int prefArrayIndent() {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   147
			String option= getCoreFormatterOption(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_EXPRESSIONS_IN_INITIALIZER_LIST);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   148
			try {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   149
				if (DefaultCodeFormatterConstants.getIndentStyle(option) == DefaultCodeFormatterConstants.INDENT_BY_ONE)
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   150
					return 1;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   151
			} catch (IllegalArgumentException e) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   152
				// ignore and return default
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   153
			}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   154
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   155
			return prefContinuationIndent(); // default
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   156
		}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   157
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   158
		private boolean prefArrayDeepIndent() {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   159
			String option= getCoreFormatterOption(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_EXPRESSIONS_IN_INITIALIZER_LIST);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   160
			try {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   161
				return DefaultCodeFormatterConstants.getIndentStyle(option) == DefaultCodeFormatterConstants.INDENT_ON_COLUMN;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   162
			} catch (IllegalArgumentException e) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   163
				// ignore and return default
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   164
			}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   165
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   166
			return true;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   167
		}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   168
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   169
		private boolean prefTernaryDeepAlign() {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   170
			String option= getCoreFormatterOption(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_CONDITIONAL_EXPRESSION);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   171
			try {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   172
				return DefaultCodeFormatterConstants.getIndentStyle(option) == DefaultCodeFormatterConstants.INDENT_ON_COLUMN;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   173
			} catch (IllegalArgumentException e) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   174
				// ignore and return default
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   175
			}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   176
			return false;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   177
		}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   178
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   179
		private int prefTernaryIndent() {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   180
			String option= getCoreFormatterOption(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_CONDITIONAL_EXPRESSION);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   181
			try {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   182
				if (DefaultCodeFormatterConstants.getIndentStyle(option) == DefaultCodeFormatterConstants.INDENT_BY_ONE)
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   183
					return 1;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   184
				else
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   185
					return prefContinuationIndent();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   186
			} catch (IllegalArgumentException e) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   187
				// ignore and return default
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   188
			}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   189
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   190
			return prefContinuationIndent();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   191
		}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   192
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   193
		private int prefCaseIndent() {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   194
			if (DefaultCodeFormatterConstants.TRUE.equals(getCoreFormatterOption(DefaultCodeFormatterConstants.FORMATTER_INDENT_SWITCHSTATEMENTS_COMPARE_TO_SWITCH)))
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   195
				return 1;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   196
			else
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   197
				return 0;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   198
		}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   199
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   200
		private int prefCaseBlockIndent() {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   201
			if (DefaultCodeFormatterConstants.TRUE.equals(getCoreFormatterOption(DefaultCodeFormatterConstants.FORMATTER_INDENT_SWITCHSTATEMENTS_COMPARE_TO_CASES)))
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   202
				return 1;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   203
			else
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   204
				return 0;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   205
		}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   206
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   207
		private int prefAssignmentIndent() {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   208
			return prefContinuationIndent();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   209
		}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   210
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   211
		private int prefSimpleIndent() {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   212
			if (prefIndentBracesForBlocks() && prefBlockIndent() == 0)
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   213
				return 1;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   214
			else
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   215
				return prefBlockIndent();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   216
		}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   217
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   218
		private int prefBracketIndent() {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   219
			return prefBlockIndent();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   220
		}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   221
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   222
		private boolean prefMethodDeclDeepIndent() {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   223
			String option= getCoreFormatterOption(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_PARAMETERS_IN_METHOD_DECLARATION);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   224
			try {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   225
				int indentStyle = DefaultCodeFormatterConstants.getIndentStyle(option);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   226
				return indentStyle == DefaultCodeFormatterConstants.INDENT_ON_COLUMN;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   227
			} catch (IllegalArgumentException e) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   228
				// ignore and return default
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   229
			}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   230
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   231
			return false;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   232
		}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   233
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   234
		private boolean prefMethodDeclFirstParameterDeepIndent() {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   235
			String option= getCoreFormatterOption(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_PARAMETERS_IN_METHOD_DECLARATION);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   236
			try {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   237
				int indentStyle = DefaultCodeFormatterConstants.getIndentStyle(option);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   238
				int wrappingStyle = DefaultCodeFormatterConstants.getWrappingStyle(option);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   239
				return indentStyle == DefaultCodeFormatterConstants.INDENT_ON_COLUMN &&
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   240
				    	(wrappingStyle == DefaultCodeFormatterConstants.WRAP_COMPACT_FIRST_BREAK ||
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   241
				    	wrappingStyle == DefaultCodeFormatterConstants.WRAP_ONE_PER_LINE);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   242
			} catch (IllegalArgumentException e) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   243
				// ignore and return default
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   244
			}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   245
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   246
			return false;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   247
		}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   248
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   249
		private int prefMethodDeclIndent() {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   250
			String option= getCoreFormatterOption(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_PARAMETERS_IN_METHOD_DECLARATION);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   251
			try {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   252
				if (DefaultCodeFormatterConstants.getIndentStyle(option) == DefaultCodeFormatterConstants.INDENT_BY_ONE)
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   253
					return 1;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   254
				else
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   255
					return prefContinuationIndent();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   256
			} catch (IllegalArgumentException e) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   257
				// ignore and return default
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   258
			}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   259
			return 1;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   260
		}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   261
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   262
		private boolean prefMethodCallDeepIndent() {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   263
			String option= getCoreFormatterOption(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_ARGUMENTS_IN_METHOD_INVOCATION);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   264
			try {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   265
				int indentStyle = DefaultCodeFormatterConstants.getIndentStyle(option);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   266
				return indentStyle == DefaultCodeFormatterConstants.INDENT_ON_COLUMN;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   267
			} catch (IllegalArgumentException e) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   268
				// ignore and return default
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   269
			}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   270
			return false; // sensible default
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   271
		}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   272
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   273
		private boolean prefMethodCallFirstParameterDeepIndent() {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   274
			String option= getCoreFormatterOption(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_ARGUMENTS_IN_METHOD_INVOCATION);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   275
			try {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   276
				int indentStyle = DefaultCodeFormatterConstants.getIndentStyle(option);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   277
				int wrappingStyle = DefaultCodeFormatterConstants.getWrappingStyle(option);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   278
				return indentStyle == DefaultCodeFormatterConstants.INDENT_ON_COLUMN &&
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   279
				    	(wrappingStyle == DefaultCodeFormatterConstants.WRAP_COMPACT_FIRST_BREAK ||
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   280
				        wrappingStyle == DefaultCodeFormatterConstants.WRAP_ONE_PER_LINE);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   281
			} catch (IllegalArgumentException e) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   282
				// ignore and return default
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   283
			}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   284
			return false; // sensible default
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   285
		}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   286
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   287
		private int prefMethodCallIndent() {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   288
			String option= getCoreFormatterOption(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_ARGUMENTS_IN_METHOD_INVOCATION);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   289
			try {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   290
				if (DefaultCodeFormatterConstants.getIndentStyle(option) == DefaultCodeFormatterConstants.INDENT_BY_ONE)
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   291
					return 1;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   292
				else
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   293
					return prefContinuationIndent();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   294
			} catch (IllegalArgumentException e) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   295
				// ignore and return default
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   296
			}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   297
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   298
			return 1; // sensible default
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   299
		}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   300
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   301
		private boolean prefParenthesisDeepIndent() {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   302
			// don't do parenthesis deep indentation
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   303
//			String option= getCoreFormatterOption(DefaultCodeFormatterConstants.FORMATTER_CONTINUATION_INDENTATION);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   304
//			try {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   305
//				return DefaultCodeFormatterConstants.getIndentStyle(option) == DefaultCodeFormatterConstants.INDENT_ON_COLUMN;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   306
//			} catch (IllegalArgumentException e) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   307
//				// ignore and return default
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   308
//			}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   309
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   310
			return false;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   311
		}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   312
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   313
		private int prefParenthesisIndent() {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   314
			return prefContinuationIndent();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   315
		}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   316
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   317
		private int prefBlockIndent() {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   318
			String option= getCoreFormatterOption(DefaultCodeFormatterConstants.FORMATTER_INDENT_STATEMENTS_COMPARE_TO_BLOCK);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   319
			if (DefaultCodeFormatterConstants.FALSE.equals(option))
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   320
				return 0;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   321
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   322
			return 1; // sensible default
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   323
		}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   324
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   325
		private int prefMethodBodyIndent() {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   326
			if (DefaultCodeFormatterConstants.FALSE.equals(getCoreFormatterOption(DefaultCodeFormatterConstants.FORMATTER_INDENT_STATEMENTS_COMPARE_TO_BODY)))
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   327
				return 0;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   328
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   329
			return 1; // sensible default
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   330
		}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   331
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   332
		private int prefTypeIndent() {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   333
			String option= getCoreFormatterOption(DefaultCodeFormatterConstants.FORMATTER_INDENT_BODY_DECLARATIONS_COMPARE_TO_ACCESS_SPECIFIER);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   334
			if (DefaultCodeFormatterConstants.FALSE.equals(option))
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   335
				return 0;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   336
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   337
			return 1; // sensible default
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   338
		}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   339
		
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   340
		private int prefAccessSpecifierIndent() {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   341
			if (DefaultCodeFormatterConstants.TRUE.equals(getCoreFormatterOption(DefaultCodeFormatterConstants.FORMATTER_INDENT_ACCESS_SPECIFIER_COMPARE_TO_TYPE_HEADER)))
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   342
				return 1;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   343
			else
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   344
				return 0;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   345
		}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   346
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   347
		private int prefAccessSpecifierExtraSpaces() {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   348
			// Hidden option that enables fractional indent of access specifiers.
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   349
			IPreferencesService prefs = Platform.getPreferencesService();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   350
			return prefs.getInt(CCorePlugin.PLUGIN_ID, CCorePlugin.PLUGIN_ID + ".formatter.indent_access_specifier_extra_spaces", 0, null); //$NON-NLS-1$
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   351
		}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   352
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   353
		private int prefNamespaceBodyIndent() {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   354
			if (DefaultCodeFormatterConstants.TRUE.equals(getCoreFormatterOption(DefaultCodeFormatterConstants.FORMATTER_INDENT_BODY_DECLARATIONS_COMPARE_TO_NAMESPACE_HEADER)))
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   355
				return prefBlockIndent();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   356
			else
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   357
				return 0;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   358
		}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   359
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   360
		private boolean prefIndentBracesForBlocks() {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   361
			return DefaultCodeFormatterConstants.NEXT_LINE_SHIFTED.equals(getCoreFormatterOption(DefaultCodeFormatterConstants.FORMATTER_BRACE_POSITION_FOR_BLOCK));
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   362
		}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   363
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   364
		private boolean prefIndentBracesForArrays() {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   365
			return DefaultCodeFormatterConstants.NEXT_LINE_SHIFTED.equals(getCoreFormatterOption(DefaultCodeFormatterConstants.FORMATTER_BRACE_POSITION_FOR_INITIALIZER_LIST));
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   366
		}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   367
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   368
		private boolean prefIndentBracesForMethods() {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   369
			return DefaultCodeFormatterConstants.NEXT_LINE_SHIFTED.equals(getCoreFormatterOption(DefaultCodeFormatterConstants.FORMATTER_BRACE_POSITION_FOR_METHOD_DECLARATION));
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   370
		}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   371
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   372
		private boolean prefIndentBracesForTypes() {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   373
			return DefaultCodeFormatterConstants.NEXT_LINE_SHIFTED.equals(getCoreFormatterOption(DefaultCodeFormatterConstants.FORMATTER_BRACE_POSITION_FOR_TYPE_DECLARATION));
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   374
		}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   375
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   376
		private int prefContinuationIndent() {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   377
			try {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   378
				return Integer.parseInt(getCoreFormatterOption(DefaultCodeFormatterConstants.FORMATTER_CONTINUATION_INDENTATION));
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   379
			} catch (NumberFormatException e) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   380
				// ignore and return default
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   381
			}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   382
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   383
			return 2; // sensible default
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   384
		}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   385
		
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   386
		private boolean hasTemplates() {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   387
			return true;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   388
		}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   389
	}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   390
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   391
	/** The document being scanned. */
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   392
	private final IDocument fDocument;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   393
	/** The indentation accumulated by <code>findReferencePosition</code>. */
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   394
	private int fIndent;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   395
	/** Extra spaces to add on top of fIndent */
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   396
	private int fExtraSpaces;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   397
	/**
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   398
	 * The absolute (character-counted) indentation offset for special cases
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   399
	 * (method defs, array initializers)
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   400
	 */
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   401
	private int fAlign;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   402
	/** The stateful scan position for the indentation methods. */
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   403
	private int fPosition;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   404
	/** The previous position. */
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   405
	private int fPreviousPos;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   406
	/** The most recent token. */
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   407
	private int fToken;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   408
	/** The line of <code>fPosition</code>. */
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   409
	private int fLine;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   410
	/**
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   411
	 * The scanner we will use to scan the document. It has to be installed
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   412
	 * on the same document as the one we get.
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   413
	 */
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   414
	private final CHeuristicScanner fScanner;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   415
	/**
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   416
	 * The CDT Core preferences.
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   417
	 */
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   418
	private final CorePrefs fPrefs;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   419
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   420
	/**
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   421
	 * Creates a new instance.
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   422
	 *
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   423
	 * @param document the document to scan
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   424
	 * @param scanner the {@link CHeuristicScanner} to be used for scanning
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   425
	 * the document. It must be installed on the same <code>IDocument</code>.
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   426
	 */
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   427
	public CIndenter(IDocument document, CHeuristicScanner scanner) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   428
		this(document, scanner, null);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   429
	}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   430
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   431
	/**
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   432
	 * Creates a new instance.
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   433
	 *
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   434
	 * @param document the document to scan
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   435
	 * @param scanner the {@link CHeuristicScanner} to be used for scanning
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   436
	 *        the document. It must be installed on the same
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   437
	 *        <code>IDocument</code>.
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   438
	 * @param project the C/C++ project to get the formatter preferences from, or
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   439
	 *        <code>null</code> to use the workspace settings
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   440
	 */
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   441
	public CIndenter(IDocument document, CHeuristicScanner scanner, ICProject project) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   442
		Assert.isNotNull(document);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   443
		Assert.isNotNull(scanner);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   444
		fDocument= document;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   445
		fScanner= scanner;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   446
		fPrefs= new CorePrefs(project);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   447
	}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   448
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   449
	/**
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   450
	 * Computes the indentation at the reference point of <code>position</code>.
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   451
	 *
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   452
	 * @param offset the offset in the document
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   453
	 * @return a String which reflects the indentation at the line in which the
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   454
	 *         reference position to <code>offset</code> resides, or <code>null</code>
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   455
	 *         if it cannot be determined
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   456
	 */
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   457
	public StringBuilder getReferenceIndentation(int offset) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   458
		return getReferenceIndentation(offset, false);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   459
	}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   460
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   461
	/**
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   462
	 * Computes the indentation at the reference point of <code>position</code>.
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   463
	 *
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   464
	 * @param offset the offset in the document
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   465
	 * @param assumeOpeningBrace <code>true</code> if an opening brace should be assumed
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   466
	 * @return a String which reflects the indentation at the line in which the
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   467
	 *         reference position to <code>offset</code> resides, or <code>null</code>
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   468
	 *         if it cannot be determined
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   469
	 */
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   470
	private StringBuilder getReferenceIndentation(int offset, boolean assumeOpeningBrace) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   471
		int unit;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   472
		if (assumeOpeningBrace)
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   473
			unit= findReferencePosition(offset, Symbols.TokenLBRACE);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   474
		else
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   475
			unit= findReferencePosition(offset, peekToken(offset));
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   476
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   477
		// if we were unable to find anything, return null
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   478
		if (unit == CHeuristicScanner.NOT_FOUND)
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   479
			return null;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   480
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   481
		return getLeadingWhitespace(unit);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   482
	}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   483
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   484
	/**
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   485
	 * Computes the indentation at <code>offset</code>.
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   486
	 *
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   487
	 * @param offset the offset in the document
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   488
	 * @return a String which reflects the correct indentation for the line in
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   489
	 *         which offset resides, or <code>null</code> if it cannot be
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   490
	 *         determined
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   491
	 */
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   492
	public StringBuilder computeIndentation(int offset) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   493
		return computeIndentation(offset, false);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   494
	}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   495
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   496
	/**
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   497
	 * Computes the indentation at <code>offset</code>.
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   498
	 *
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   499
	 * @param offset the offset in the document
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   500
	 * @param assumeOpeningBrace <code>true</code> if an opening brace should be assumed
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   501
	 * @return a String which reflects the correct indentation for the line in
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   502
	 *         which offset resides, or <code>null</code> if it cannot be
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   503
	 *         determined
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   504
	 */
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   505
	public StringBuilder computeIndentation(int offset, boolean assumeOpeningBrace) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   506
		StringBuilder reference= getReferenceIndentation(offset, assumeOpeningBrace);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   507
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   508
		// handle special alignment
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   509
		if (fAlign != CHeuristicScanner.NOT_FOUND) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   510
			try {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   511
				// a special case has been detected.
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   512
				IRegion line= fDocument.getLineInformationOfOffset(fAlign);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   513
				int lineOffset= line.getOffset();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   514
				return createIndent(lineOffset, fAlign, false);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   515
			} catch (BadLocationException e) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   516
				return null;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   517
			}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   518
		}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   519
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   520
		if (reference == null)
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   521
			return null;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   522
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   523
		// Add additional indent
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   524
		return createReusingIndent(reference, fIndent, fExtraSpaces);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   525
	}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   526
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   527
	/**
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   528
	 * Computes the indentation for a continuation line at <code>offset</code>.
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   529
	 *
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   530
	 * @param offset the offset in the document
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   531
	 * @return a StringBuilder which reflects the correct indentation for
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   532
	 *         the line in  which offset resides, or <code>null</code> if it cannot be
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   533
	 *         determined.
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   534
	 * @throws BadLocationException
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   535
	 */
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   536
	public StringBuilder computeContinuationLineIndentation(int offset) throws BadLocationException {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   537
		StringBuilder reference= getLeadingWhitespace(offset);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   538
		IRegion line= fDocument.getLineInformationOfOffset(offset);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   539
		String string= fDocument.get(line.getOffset(), offset - line.getOffset());
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   540
		if (string.trim().length() == 0)
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   541
			return reference;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   542
		// Add additional indent
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   543
		return createReusingIndent(reference, fPrefs.prefContinuationIndent, 0);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   544
	}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   545
	
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   546
	/**
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   547
	 * Computes the length of a <code>CharacterSequence</code>, counting
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   548
	 * a tab character as the size until the next tab stop and every other
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   549
	 * character as one.
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   550
	 *
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   551
	 * @param indent the string to measure
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   552
	 * @return the visual length in characters
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   553
	 */
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   554
	private int computeVisualLength(CharSequence indent) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   555
		final int tabSize= fPrefs.prefTabSize;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   556
		int length= 0;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   557
		for (int i= 0; i < indent.length(); i++) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   558
			char ch= indent.charAt(i);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   559
			switch (ch) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   560
			case '\t':
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   561
				if (tabSize > 0) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   562
					int reminder= length % tabSize;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   563
					length += tabSize - reminder;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   564
				}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   565
				break;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   566
			case ' ':
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   567
				length++;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   568
				break;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   569
			}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   570
		}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   571
		return length;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   572
	}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   573
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   574
	/**
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   575
	 * Strips any characters off the end of <code>reference</code> that exceed
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   576
	 * <code>indentLength</code>.
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   577
	 *
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   578
	 * @param reference the string to measure
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   579
	 * @param indentLength the maximum visual indentation length
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   580
	 * @return the stripped <code>reference</code>
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   581
	 */
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   582
	private StringBuilder stripExceedingChars(StringBuilder reference, int indentLength) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   583
		final int tabSize= fPrefs.prefTabSize;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   584
		int measured= 0;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   585
		int chars= reference.length();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   586
		int i= 0;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   587
		for (; measured < indentLength && i < chars; i++) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   588
			char ch= reference.charAt(i);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   589
			switch (ch) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   590
			case '\t':
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   591
				if (tabSize > 0) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   592
					int reminder= measured % tabSize;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   593
					measured += tabSize - reminder;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   594
				}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   595
				break;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   596
			case ' ':
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   597
				measured++;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   598
				break;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   599
			}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   600
		}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   601
		int deleteFrom= measured > indentLength ? i - 1 : i;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   602
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   603
		return reference.delete(deleteFrom, chars);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   604
	}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   605
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   606
	/**
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   607
	 * Returns the indentation of the line at <code>offset</code> as a
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   608
	 * <code>StringBuilder</code>. If the offset is not valid, the empty string
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   609
	 * is returned.
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   610
	 *
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   611
	 * @param offset the offset in the document
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   612
	 * @return the indentation (leading whitespace) of the line in which
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   613
	 * 		   <code>offset</code> is located
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   614
	 */
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   615
	private StringBuilder getLeadingWhitespace(int offset) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   616
		StringBuilder indent= new StringBuilder();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   617
		try {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   618
			IRegion line= fDocument.getLineInformationOfOffset(offset);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   619
			int lineOffset= line.getOffset();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   620
			int nonWS= fScanner.findNonWhitespaceForwardInAnyPartition(lineOffset, lineOffset + line.getLength());
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   621
			indent.append(fDocument.get(lineOffset, nonWS - lineOffset));
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   622
			return indent;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   623
		} catch (BadLocationException e) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   624
			return indent;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   625
		}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   626
	}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   627
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   628
	/**
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   629
	 * Creates an indentation string of the length indent - start, consisting of
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   630
	 * the content in <code>fDocument</code> in the range [start, indent),
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   631
	 * with every character replaced by a space except for tabs, which are kept
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   632
	 * as such.
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   633
	 * <p>
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   634
	 * If <code>convertSpaceRunsToTabs</code> is <code>true</code>, every
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   635
	 * run of the number of spaces that make up a tab are replaced by a tab
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   636
	 * character. If it is not set, no conversion takes place, but tabs in the
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   637
	 * original range are still copied verbatim.
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   638
	 * </p>
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   639
	 *
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   640
	 * @param start the start of the document region to copy the indent from
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   641
	 * @param indent the exclusive end of the document region to copy the indent
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   642
	 *        from
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   643
	 * @param convertSpaceRunsToTabs whether to convert consecutive runs of
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   644
	 *        spaces to tabs
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   645
	 * @return the indentation corresponding to the document content specified
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   646
	 *         by <code>start</code> and <code>indent</code>
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   647
	 */
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   648
	private StringBuilder createIndent(int start, final int indent, final boolean convertSpaceRunsToTabs) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   649
		final boolean convertTabs= fPrefs.prefUseTabs && convertSpaceRunsToTabs;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   650
		final int tabLen= fPrefs.prefTabSize;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   651
		final StringBuilder ret= new StringBuilder();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   652
		try {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   653
			int spaces= 0;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   654
			while (start < indent) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   655
				char ch= fDocument.getChar(start);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   656
				if (ch == '\t') {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   657
					ret.append('\t');
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   658
					spaces= 0;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   659
				} else if (convertTabs) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   660
					spaces++;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   661
					if (spaces == tabLen) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   662
						ret.append('\t');
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   663
						spaces= 0;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   664
					}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   665
				} else {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   666
					ret.append(' ');
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   667
				}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   668
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   669
				start++;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   670
			}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   671
			// remainder
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   672
			while (spaces-- > 0)
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   673
				ret.append(' ');
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   674
		} catch (BadLocationException e) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   675
		}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   676
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   677
		return ret;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   678
	}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   679
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   680
	/**
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   681
	 * Creates a string with a visual length of the given
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   682
	 * <code>indentationSize</code>.
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   683
	 *
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   684
	 * @param buffer the original indent to reuse if possible
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   685
	 * @param additional the additional indentation units to add or subtract to
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   686
	 *        reference
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   687
	 * @param extraSpaces additional spaces to add to indentation.
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   688
	 * @return the modified <code>buffer</code> reflecting the indentation
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   689
	 *         adapted to <code>additional</code>
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   690
	 */
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   691
	public StringBuilder createReusingIndent(StringBuilder buffer, int additional, int extraSpaces) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   692
		int refLength= computeVisualLength(buffer);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   693
		int addLength= fPrefs.prefIndentationSize * additional + extraSpaces; // may be < 0
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   694
		int totalLength= Math.max(0, refLength + addLength);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   695
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   696
		// copy the reference indentation for the indent up to the last tab
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   697
		// stop within the maxCopy area
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   698
		int minLength= Math.min(totalLength, refLength);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   699
		int tabSize= fPrefs.prefTabSize;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   700
		int maxCopyLength= tabSize > 0 ? minLength - minLength % tabSize : minLength; // maximum indent to copy
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   701
		stripExceedingChars(buffer, maxCopyLength);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   702
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   703
		// add additional indent
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   704
		int missing= totalLength - maxCopyLength;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   705
		final int tabs, spaces;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   706
		if (CCorePlugin.SPACE.equals(fPrefs.prefTabChar)) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   707
			tabs= 0;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   708
			spaces= missing;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   709
		} else {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   710
			tabs= tabSize > 0 ? missing / tabSize : 0;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   711
			spaces= tabSize > 0 ? missing % tabSize : missing;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   712
		}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   713
		for (int i= 0; i < tabs; i++)
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   714
			buffer.append('\t');
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   715
		for (int i= 0; i < spaces; i++)
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   716
			buffer.append(' ');
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   717
		return buffer;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   718
	}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   719
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   720
	/**
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   721
	 * Returns relative indent of continuation lines.
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   722
	 * @return a number of indentation units.
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   723
	 */
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   724
	public int getContinuationLineIndent() {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   725
		return fPrefs.prefContinuationIndent;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   726
	}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   727
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   728
	/**
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   729
	 * Returns the reference position regarding to indentation for <code>offset</code>,
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   730
	 * or <code>NOT_FOUND</code>. This method calls
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   731
	 * {@link #findReferencePosition(int, int) findReferencePosition(offset, nextChar)} where
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   732
	 * <code>nextChar</code> is the next character after <code>offset</code>.
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   733
	 *
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   734
	 * @param offset the offset for which the reference is computed
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   735
	 * @return the reference statement relative to which <code>offset</code>
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   736
	 *         should be indented, or {@link CHeuristicScanner#NOT_FOUND}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   737
	 */
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   738
	public int findReferencePosition(int offset) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   739
		return findReferencePosition(offset, peekToken(offset));
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   740
	}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   741
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   742
	/**
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   743
	 * Peeks the next token in the document that comes after <code>offset</code>
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   744
	 * on the same line as <code>offset</code>.
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   745
	 *
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   746
	 * @param offset the offset into document
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   747
	 * @return the token symbol of the next element, or TokenEOF if there is none
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   748
	 */
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   749
	private int peekToken(int offset) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   750
		if (offset < fDocument.getLength()) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   751
			try {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   752
				IRegion line= fDocument.getLineInformationOfOffset(offset);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   753
				int lineOffset= line.getOffset();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   754
				int next= fScanner.nextToken(offset, lineOffset + line.getLength());
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   755
				return next;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   756
			} catch (BadLocationException e) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   757
			}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   758
		}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   759
		return Symbols.TokenEOF;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   760
	}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   761
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   762
	/**
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   763
	 * Returns the reference position regarding to indentation for <code>position</code>,
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   764
	 * or <code>NOT_FOUND</code>.
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   765
	 *
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   766
	 * <p>If <code>peekNextChar</code> is <code>true</code>, the next token after
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   767
	 * <code>offset</code> is read and taken into account when computing the
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   768
	 * indentation. Currently, if the next token is the first token on the line
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   769
	 * (i.e. only preceded by whitespace), the following tokens are specially
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   770
	 * handled:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   771
	 * <ul>
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   772
	 * 	<li><code>switch</code> labels are indented relative to the switch block</li>
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   773
	 * 	<li>opening curly braces are aligned correctly with the introducing code</li>
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   774
	 * 	<li>closing curly braces are aligned properly with the introducing code of
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   775
	 * 		the matching opening brace</li>
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   776
	 * 	<li>closing parenthesis' are aligned with their opening peer</li>
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   777
	 * 	<li>the <code>else</code> keyword is aligned with its <code>if</code>, anything
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   778
	 * 		else is aligned normally (i.e. with the base of any introducing statements).</li>
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   779
	 *  <li>if there is no token on the same line after <code>offset</code>, the indentation
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   780
	 * 		is the same as for an <code>else</code> keyword</li>
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   781
	 * </ul>
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   782
	 *
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   783
	 * @param offset the offset for which the reference is computed
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   784
	 * @param nextToken the next token to assume in the document
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   785
	 * @return the reference statement relative to which <code>offset</code>
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   786
	 *         should be indented, or {@link CHeuristicScanner#NOT_FOUND}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   787
	 */
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   788
	public int findReferencePosition(int offset, int nextToken) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   789
		boolean danglingElse= false;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   790
		boolean cancelIndent= false; // If set to true, fIndent is ignored.
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   791
		int extraIndent= 0; // Can be either positive or negative.
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   792
		boolean matchBrace= false;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   793
		boolean matchParen= false;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   794
		boolean matchCase= false;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   795
		boolean matchAccessSpecifier= false;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   796
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   797
		// Account for un-indentation characters already typed in, but after position.
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   798
		// If they are on a line by themselves, the indentation gets adjusted accordingly.
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   799
		//
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   800
		// Also account for a dangling else.
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   801
		if (offset < fDocument.getLength()) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   802
			try {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   803
				IRegion line= fDocument.getLineInformationOfOffset(offset);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   804
				int lineOffset= line.getOffset();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   805
				int prevPos= Math.max(offset - 1, 0);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   806
				boolean isFirstTokenOnLine= fDocument.get(lineOffset, prevPos + 1 - lineOffset).trim().length() == 0;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   807
				int prevToken= fScanner.previousToken(prevPos, CHeuristicScanner.UNBOUND);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   808
				boolean bracelessBlockStart= fScanner.isBracelessBlockStart(prevPos, CHeuristicScanner.UNBOUND);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   809
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   810
				switch (nextToken) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   811
				case Symbols.TokenELSE:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   812
					danglingElse= true;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   813
					break;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   814
					
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   815
				case Symbols.TokenCASE:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   816
				case Symbols.TokenDEFAULT:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   817
					if (isFirstTokenOnLine)
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   818
						matchCase= true;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   819
					break;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   820
					
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   821
				case Symbols.TokenPUBLIC:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   822
				case Symbols.TokenPROTECTED:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   823
				case Symbols.TokenPRIVATE:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   824
					if (isFirstTokenOnLine)
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   825
						matchAccessSpecifier= true;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   826
					break;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   827
					
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   828
				case Symbols.TokenLBRACE: // for opening-brace-on-new-line style
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   829
					if (bracelessBlockStart) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   830
						extraIndent= fPrefs.prefIndentBracesForBlocks ? 0 : -1;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   831
					} else if (prevToken == Symbols.TokenCOLON && !fPrefs.prefIndentBracesForBlocks) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   832
						extraIndent= -1;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   833
					} else if ((prevToken == Symbols.TokenEQUAL || prevToken == Symbols.TokenRBRACKET) &&
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   834
							!fPrefs.prefIndentBracesForArrays) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   835
						cancelIndent= true;
138
e0657161c0cc bug 11072 - fix problems with formatting around const functions
dadubrow
parents: 37
diff changeset
   836
					} else if ((prevToken == Symbols.TokenRPAREN || prevToken == Symbols.TokenCONST) && fPrefs.prefIndentBracesForMethods) {
37
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   837
						extraIndent= 1;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   838
					} else if (prevToken == Symbols.TokenIDENT && fPrefs.prefIndentBracesForTypes) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   839
						extraIndent= 1;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   840
					}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   841
					break;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   842
					
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   843
				case Symbols.TokenRBRACE: // closing braces get unindented
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   844
					if (isFirstTokenOnLine || prevToken != Symbols.TokenLBRACE)
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   845
						matchBrace= true;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   846
					break;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   847
					
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   848
				case Symbols.TokenRPAREN:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   849
					if (isFirstTokenOnLine)
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   850
						matchParen= true;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   851
					break;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   852
				}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   853
			} catch (BadLocationException e) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   854
			}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   855
		} else {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   856
			// don't assume an else could come if we are at the end of file
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   857
			danglingElse= false;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   858
		}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   859
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   860
		int ref= findReferencePosition(offset, danglingElse, matchBrace, matchParen, matchCase,
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   861
				matchAccessSpecifier);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   862
		if (cancelIndent) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   863
			fIndent = 0;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   864
		} else if (extraIndent > 0) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   865
			fAlign= CHeuristicScanner.NOT_FOUND;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   866
			fIndent += extraIndent;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   867
		} else {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   868
			fIndent += extraIndent;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   869
		}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   870
		return ref;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   871
	}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   872
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   873
	/**
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   874
	 * Returns the reference position regarding to indentation for <code>position</code>,
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   875
	 * or <code>NOT_FOUND</code>.<code>fIndent</code> will contain the
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   876
	 * relative indentation (in indentation units, not characters) after the
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   877
	 * call. If there is a special alignment (e.g. for a method declaration
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   878
	 * where parameters should be aligned), <code>fAlign</code> will contain
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   879
	 * the absolute position of the alignment reference in <code>fDocument</code>,
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   880
	 * otherwise <code>fAlign</code> is set to <code>CHeuristicScanner.NOT_FOUND</code>.
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   881
	 *
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   882
	 * @param offset the offset for which the reference is computed
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   883
	 * @param danglingElse whether a dangling else should be assumed at <code>position</code>
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   884
	 * @param matchBrace whether the position of the matching brace should be
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   885
	 *            returned instead of doing code analysis
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   886
	 * @param matchParen whether the position of the matching parenthesis
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   887
	 *            should be returned instead of doing code analysis
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   888
	 * @param matchCase whether the position of a switch statement reference
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   889
	 *            should be returned (either an earlier case statement or the
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   890
	 *            switch block brace)
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   891
	 * @param matchAccessSpecifier whether the position of a class body reference
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   892
	 *            should be returned (either an earlier public/protected/private
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   893
	 *            or the class body brace)
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   894
	 * @return the reference statement relative to which <code>position</code>
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   895
	 *         should be indented, or {@link CHeuristicScanner#NOT_FOUND}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   896
	 */
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   897
	public int findReferencePosition(int offset, boolean danglingElse, boolean matchBrace, boolean matchParen,
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   898
			boolean matchCase, boolean matchAccessSpecifier) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   899
		fIndent= 0; // the indentation modification
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   900
		fAlign= CHeuristicScanner.NOT_FOUND;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   901
		fPosition= offset;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   902
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   903
		// forward cases
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   904
		// An unindentation happens sometimes if the next token is special, namely on braces, parens and case
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   905
		// labels align braces, but handle the case where we align with the method declaration start instead
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   906
		// of the opening brace.
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   907
		if (matchBrace) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   908
			if (skipScope(Symbols.TokenLBRACE, Symbols.TokenRBRACE)) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   909
				try {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   910
					// Align with the opening brace that is on a line by its own
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   911
					int lineOffset= fDocument.getLineOffset(fLine);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   912
					if (lineOffset <= fPosition && fDocument.get(lineOffset, fPosition - lineOffset).trim().length() == 0)
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   913
						return fPosition;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   914
				} catch (BadLocationException e) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   915
					// Concurrent modification - walk default path
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   916
				}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   917
				// If the opening brace is not on the start of the line, skip to the start
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   918
				int pos= skipToStatementStart(true, true);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   919
				fIndent= 0; // indent is aligned with reference position
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   920
				return pos;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   921
			} else {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   922
				// If we can't find the matching brace, the heuristic is to unindent
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   923
				// by one against the normal position
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   924
				int pos= findReferencePosition(offset, danglingElse, false, matchParen, matchCase,
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   925
						matchAccessSpecifier);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   926
				fIndent--;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   927
				return pos;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   928
			}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   929
		}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   930
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   931
		// Align parentheses
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   932
		if (matchParen) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   933
			if (skipScope(Symbols.TokenLPAREN, Symbols.TokenRPAREN)) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   934
				return fPosition;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   935
			} else {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   936
				// if we can't find the matching paren, the heuristic is to unindent
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   937
				// by one against the normal position
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   938
				int pos= findReferencePosition(offset, danglingElse, matchBrace, false, matchCase,
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   939
						matchAccessSpecifier);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   940
				fIndent--;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   941
				return pos;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   942
			}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   943
		}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   944
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   945
		// The only reliable way to get case labels aligned (due to many different styles of using braces in
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   946
		// a block) is to go for another case statement, or the scope opening brace.
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   947
		if (matchCase) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   948
			return matchCaseAlignment();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   949
		}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   950
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   951
		// the only reliable way to get access specifiers aligned (due to many different styles of using
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   952
		// braces in a block) is to go for another access specifier, or the scope opening brace.
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   953
		if (matchAccessSpecifier) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   954
			return matchAccessSpecifierAlignment();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   955
		}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   956
		
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   957
		nextToken();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   958
		// Skip access specifiers
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   959
		while (fToken == Symbols.TokenCOLON && isAccessSpecifier()) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   960
			nextToken();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   961
		}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   962
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   963
		int line= fLine;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   964
		switch (fToken) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   965
		case Symbols.TokenGREATERTHAN:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   966
		case Symbols.TokenRBRACE:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   967
			// skip the block and fall through
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   968
			// if we can't complete the scope, reset the scan position
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   969
			int pos= fPosition;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   970
			if (!skipScope())
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   971
				fPosition= pos;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   972
			return skipToStatementStart(danglingElse, false);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   973
		case Symbols.TokenSEMICOLON:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   974
			// this is the 90% case: after a statement block
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   975
			// the end of the previous statement / block previous.end
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   976
			// search to the end of the statement / block before the previous;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   977
			// the token just after that is previous.start
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   978
			return skipToStatementStart(danglingElse, false);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   979
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   980
		// scope introduction: special treat who special is
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   981
		case Symbols.TokenLPAREN:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   982
		case Symbols.TokenLBRACE:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   983
		case Symbols.TokenLBRACKET:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   984
			return handleScopeIntroduction(Math.min(offset + 1, fDocument.getLength()), true);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   985
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   986
		case Symbols.TokenEOF:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   987
			// trap when hitting start of document
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   988
			return CHeuristicScanner.NOT_FOUND;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   989
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   990
		case Symbols.TokenEQUAL:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   991
			// indent assignments
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   992
			fIndent= fPrefs.prefAssignmentIndent;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   993
			return fPosition;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   994
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   995
		case Symbols.TokenCOLON:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   996
			pos= fPosition;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   997
			if (looksLikeCaseStatement()) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   998
				fIndent= fPrefs.prefCaseBlockIndent;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   999
				return pos;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1000
			}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1001
			fPosition= pos;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1002
			if (looksLikeTypeInheritanceDecl()) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1003
				fIndent= fPrefs.prefBlockIndent;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1004
				return pos;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1005
			}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1006
			fPosition= pos;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1007
			if (looksLikeConstructorInitializer()) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1008
				fIndent= fPrefs.prefBlockIndent;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1009
				return pos;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1010
			}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1011
			fPosition= pos;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1012
			if (isConditional()) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1013
				fPosition= offset;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1014
				fLine= line;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1015
				return skipToPreviousListItemOrListStart();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1016
			}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1017
			fPosition= pos;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1018
			return skipToStatementStart(danglingElse, false);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1019
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1020
		case Symbols.TokenQUESTIONMARK:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1021
			if (fPrefs.prefTernaryDeepAlign) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1022
				setFirstElementAlignment(fPosition, offset + 1);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1023
			} else {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1024
				fIndent= fPrefs.prefTernaryIndent;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1025
			}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1026
			return fPosition;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1027
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1028
		// indentation for blockless introducers:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1029
		case Symbols.TokenDO:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1030
		case Symbols.TokenWHILE:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1031
		case Symbols.TokenELSE:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1032
			fIndent= fPrefs.prefSimpleIndent;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1033
			return fPosition;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1034
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1035
		case Symbols.TokenTRY:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1036
			return skipToStatementStart(danglingElse, false);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1037
138
e0657161c0cc bug 11072 - fix problems with formatting around const functions
dadubrow
parents: 37
diff changeset
  1038
		case Symbols.TokenCONST:
e0657161c0cc bug 11072 - fix problems with formatting around const functions
dadubrow
parents: 37
diff changeset
  1039
			nextToken();
e0657161c0cc bug 11072 - fix problems with formatting around const functions
dadubrow
parents: 37
diff changeset
  1040
			if (fToken != Symbols.TokenRPAREN) {
e0657161c0cc bug 11072 - fix problems with formatting around const functions
dadubrow
parents: 37
diff changeset
  1041
				return skipToPreviousListItemOrListStart();
e0657161c0cc bug 11072 - fix problems with formatting around const functions
dadubrow
parents: 37
diff changeset
  1042
			}
e0657161c0cc bug 11072 - fix problems with formatting around const functions
dadubrow
parents: 37
diff changeset
  1043
			// could be const method decl
e0657161c0cc bug 11072 - fix problems with formatting around const functions
dadubrow
parents: 37
diff changeset
  1044
			//$FALL-THROUGH$
37
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1045
		case Symbols.TokenRPAREN:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1046
			if (skipScope(Symbols.TokenLPAREN, Symbols.TokenRPAREN)) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1047
				int scope= fPosition;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1048
				nextToken();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1049
				if (fToken == Symbols.TokenIF || fToken == Symbols.TokenWHILE || fToken == Symbols.TokenFOR) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1050
					fIndent= fPrefs.prefSimpleIndent;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1051
					return fPosition;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1052
				}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1053
				if (fToken == Symbols.TokenSWITCH) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1054
					return fPosition;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1055
				}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1056
				fPosition= scope;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1057
				if (looksLikeMethodDecl()) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1058
					return skipToStatementStart(danglingElse, false);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1059
				}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1060
				if (fToken == Symbols.TokenCATCH) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1061
					return skipToStatementStart(danglingElse, false);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1062
				}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1063
				fPosition= scope;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1064
				if (looksLikeAnonymousTypeDecl()) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1065
					return skipToStatementStart(danglingElse, false);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1066
				}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1067
			}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1068
			// restore
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1069
			fPosition= offset;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1070
			fLine= line;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1071
			// else: fall through to default
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1072
			return skipToPreviousListItemOrListStart();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1073
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1074
		case Symbols.TokenCOMMA:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1075
			// inside a list of some type
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1076
			// easy if there is already a list item before with its own indentation - we just align
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1077
			// if not: take the start of the list ( LPAREN, LBRACE, LBRACKET ) and either align or
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1078
			// indent by list-indent
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1079
			return skipToPreviousListItemOrListStart();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1080
		default:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1081
			// inside whatever we don't know about: similar to the list case:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1082
			// if we are inside a continued expression, then either align with a previous line that
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1083
			// has indentation or indent from the expression start line (either a scope introducer
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1084
			// or the start of the expression).
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1085
			return skipToPreviousListItemOrListStart();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1086
		}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1087
	}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1088
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1089
	/**
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1090
	 * Test whether an identifier encountered during scanning is part of
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1091
	 * a type declaration, by scanning backward and ignoring any identifiers, commas,
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1092
	 * and colons until we hit <code>class</code>, <code>struct</code>, <code>union</code>,
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1093
	 * or <code>enum</code>.  If any braces, semicolons, or parentheses are encountered,
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1094
	 * this is not a type declaration.
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1095
	 * @return the reference offset of the start of the statement
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1096
	 */
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1097
	private int matchTypeDeclaration() {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1098
		while (true) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1099
			nextToken();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1100
			if (fToken == Symbols.TokenIDENT
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1101
					|| fToken == Symbols.TokenCOMMA
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1102
					|| fToken == Symbols.TokenCOLON
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1103
					|| fToken == Symbols.TokenPUBLIC
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1104
					|| fToken == Symbols.TokenPROTECTED
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1105
					|| fToken == Symbols.TokenPRIVATE) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1106
				continue;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1107
			}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1108
			if (fToken == Symbols.TokenCLASS
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1109
					|| fToken == Symbols.TokenSTRUCT
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1110
					|| fToken == Symbols.TokenUNION
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1111
					|| fToken == Symbols.TokenENUM) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1112
				// inside a type declaration?  Only so if not preceded by '(' or ',' as in
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1113
				// a parameter list.  To be safe, only accept ';' or EOF
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1114
				int pos= fPosition;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1115
				nextToken();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1116
				if (fToken == Symbols.TokenSEMICOLON || fToken == Symbols.TokenEOF) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1117
					return pos;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1118
				} else {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1119
					return CHeuristicScanner.NOT_FOUND;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1120
				}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1121
			} else {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1122
				return CHeuristicScanner.NOT_FOUND;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1123
			}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1124
		}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1125
	}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1126
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1127
	/**
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1128
	 * Test whether the colon at the current position marks a case statement
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1129
	 * 
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1130
	 * @return <code>true</code> if this looks like a case statement
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1131
	 */
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1132
	private boolean looksLikeCaseStatement() {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1133
		nextToken();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1134
		switch (fToken) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1135
		case Symbols.TokenCASE:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1136
			// char literal got skipped
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1137
			return true;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1138
		case Symbols.TokenIDENT:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1139
			nextToken();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1140
			while (skipQualifiers()) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1141
				nextToken();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1142
			}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1143
			if (fToken == Symbols.TokenCASE) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1144
				return true;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1145
			}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1146
			break;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1147
		case Symbols.TokenOTHER:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1148
			nextToken();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1149
			if (fToken == Symbols.TokenCASE) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1150
				return true;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1151
			}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1152
			break;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1153
		case Symbols.TokenDEFAULT:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1154
			return true;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1155
		}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1156
		return false;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1157
	}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1158
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1159
	/**
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1160
	 * Test whether the colon at the current position marks a type inheritance decl.
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1161
	 * 
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1162
	 * @return <code>true</code> if this looks like a type inheritance decl.
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1163
	 */
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1164
	private boolean looksLikeTypeInheritanceDecl() {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1165
		nextToken();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1166
		switch (fToken) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1167
		case Symbols.TokenIDENT:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1168
			nextToken();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1169
			while (skipQualifiers()) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1170
				nextToken();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1171
			}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1172
			switch (fToken) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1173
			case Symbols.TokenCLASS:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1174
			case Symbols.TokenSTRUCT:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1175
			case Symbols.TokenUNION:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1176
				return true;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1177
			}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1178
			break;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1179
		}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1180
		return false;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1181
	}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1182
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1183
	/**
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1184
	 * Test whether the colon at the current position marks a constructor initializer list.
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1185
	 * 
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1186
	 * @return <code>true</code> if this looks like a constructor initializer list.
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1187
	 */
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1188
	private boolean looksLikeConstructorInitializer() {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1189
		nextToken();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1190
		if (fToken != Symbols.TokenRPAREN) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1191
			return false;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1192
		}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1193
		if (!skipScope()) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1194
			return false;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1195
		}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1196
		nextToken();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1197
		if (fToken == Symbols.TokenTHROW) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1198
			nextToken();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1199
			if (fToken != Symbols.TokenRPAREN) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1200
				return false;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1201
			}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1202
			if (!skipScope()) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1203
				return false;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1204
			}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1205
			nextToken();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1206
		}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1207
		if (fToken != Symbols.TokenIDENT) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1208
			return false;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1209
		}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1210
		nextToken();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1211
		switch (fToken) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1212
		case Symbols.TokenCOLON:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1213
			nextToken();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1214
			switch (fToken) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1215
			case Symbols.TokenCOLON:  // A::A() :
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1216
			case Symbols.TokenPUBLIC:  // public: A() :
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1217
			case Symbols.TokenPROTECTED:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1218
			case Symbols.TokenPRIVATE:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1219
				return true;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1220
			}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1221
			return false;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1222
			
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1223
		case Symbols.TokenLBRACE:  // class A { A() :
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1224
		case Symbols.TokenRBRACE:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1225
		case Symbols.TokenSEMICOLON:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1226
			return true;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1227
		}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1228
		return false;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1229
	}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1230
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1231
	/**
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1232
	 * Test whether the colon at the current position marks an access specifier.
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1233
	 * 
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1234
	 * @return <code>true</code> if current position marks an access specifier
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1235
	 */
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1236
	private boolean isAccessSpecifier() {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1237
		int pos= fPosition;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1238
		int token = fToken;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1239
		nextToken();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1240
		switch (fToken) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1241
		case Symbols.TokenPUBLIC:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1242
		case Symbols.TokenPROTECTED:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1243
		case Symbols.TokenPRIVATE:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1244
			return true;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1245
		}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1246
		fToken = token;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1247
		fPosition= pos;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1248
		return false;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1249
	}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1250
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1251
	/**
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1252
	 * Skips to the start of a statement that ends at the current position.
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1253
	 *
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1254
	 * @param danglingElse whether to indent aligned with the last <code>if</code>
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1255
	 * @param isInBlock whether the current position is inside a block, which limits the search scope to
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1256
	 *   the next scope introducer
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1257
	 * @return the reference offset of the start of the statement
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1258
	 */
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1259
	private int skipToStatementStart(boolean danglingElse, boolean isInBlock) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1260
		final int NOTHING= 0;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1261
		final int READ_PARENS= 1;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1262
		final int READ_IDENT= 2;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1263
		int mayBeMethodBody= NOTHING;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1264
		boolean isTypeBody= false;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1265
		int startLine = fLine;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1266
		while (true) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1267
			int prevToken= fToken;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1268
			nextToken();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1269
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1270
			if (isInBlock) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1271
				switch (fToken) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1272
				// exit on all block introducers
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1273
				case Symbols.TokenIF:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1274
				case Symbols.TokenELSE:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1275
				case Symbols.TokenCATCH:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1276
				case Symbols.TokenDO:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1277
				case Symbols.TokenWHILE:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1278
				case Symbols.TokenFOR:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1279
				case Symbols.TokenTRY:
140
6d6cf3bdff43 Bug 11179 fix indentation for blocks
dadubrow
parents: 138
diff changeset
  1280
					fIndent += fPrefs.prefIndentBracesForBlocks ? 1 : 0;
37
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1281
					return fPosition;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1282
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1283
				case Symbols.TokenCLASS:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1284
				case Symbols.TokenENUM:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1285
				case Symbols.TokenSTRUCT:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1286
				case Symbols.TokenUNION:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1287
					isTypeBody= true;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1288
					break;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1289
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1290
				case Symbols.TokenSWITCH:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1291
					fIndent= fPrefs.prefCaseIndent;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1292
					return fPosition;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1293
				}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1294
			}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1295
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1296
			if (fToken == Symbols.TokenSEMICOLON && fLine == startLine) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1297
				// Skip semicolons on the same line. Otherwise we may never reach beginning of a 'for'
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1298
				// statement.
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1299
				continue;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1300
			}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1301
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1302
			switch (fToken) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1303
			// scope introduction through: LPAREN, LBRACE, LBRACKET
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1304
			// search stop on SEMICOLON, RBRACE, COLON, EOF
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1305
			// -> the next token is the start of the statement (i.e. previousPos when backward scanning)
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1306
			case Symbols.TokenLPAREN:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1307
				if (peekToken() == Symbols.TokenFOR) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1308
					nextToken();  // Consume 'for'
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1309
					fIndent = fPrefs.prefContinuationIndent;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1310
					return fPosition;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1311
				}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1312
				break;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1313
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1314
			case Symbols.TokenLBRACE:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1315
			case Symbols.TokenSEMICOLON:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1316
			case Symbols.TokenEOF:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1317
				if (isInBlock)
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1318
					fIndent= getBlockIndent(mayBeMethodBody == READ_IDENT, isTypeBody);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1319
				// else: fIndent set by previous calls
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1320
				return fPreviousPos;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1321
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1322
			case Symbols.TokenCOLON:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1323
				int pos= fPreviousPos;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1324
				if (!isConditional())
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1325
					return pos;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1326
				break;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1327
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1328
			case Symbols.TokenRBRACE:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1329
				// RBRACE is a little tricky: it can be the end of an array definition, but
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1330
				// usually it is the end of a previous block
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1331
				pos= fPreviousPos; // store state
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1332
				if (skipScope()) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1333
					if (looksLikeArrayInitializerIntro()) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1334
						continue; // it's an array
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1335
					}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1336
					if (prevToken == Symbols.TokenSEMICOLON) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1337
						// end of type def
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1338
						continue;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1339
					}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1340
				}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1341
				if (isInBlock)
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1342
					fIndent= getBlockIndent(mayBeMethodBody == READ_IDENT, isTypeBody);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1343
				return pos; // it's not - do as with all the above
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1344
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1345
			// scopes: skip them
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1346
			case Symbols.TokenRPAREN:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1347
				if (isInBlock)
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1348
					mayBeMethodBody= READ_PARENS;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1349
				// fall thru
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1350
				pos= fPreviousPos;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1351
				if (skipScope())
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1352
					break;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1353
				else
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1354
					return pos;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1355
			case Symbols.TokenRBRACKET:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1356
				pos= fPreviousPos;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1357
				if (skipScope())
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1358
					break;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1359
				else
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1360
					return pos;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1361
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1362
			// IF / ELSE: align the position after the conditional block with the if
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1363
			// so we are ready for an else, except if danglingElse is false
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1364
			// in order for this to work, we must skip an else to its if
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1365
			case Symbols.TokenIF:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1366
				if (danglingElse)
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1367
					return fPosition;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1368
				else
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1369
					break;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1370
			case Symbols.TokenELSE:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1371
				// skip behind the next if, as we have that one covered
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1372
				pos= fPosition;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1373
				if (skipNextIF())
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1374
					break;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1375
				else
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1376
					return pos;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1377
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1378
			case Symbols.TokenDO:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1379
				// align the WHILE position with its do
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1380
				return fPosition;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1381
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1382
			case Symbols.TokenWHILE:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1383
				// this one is tricky: while can be the start of a while loop
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1384
				// or the end of a do - while
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1385
				pos= fPosition;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1386
				if (hasMatchingDo()) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1387
					// continue searching from the DO on
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1388
					break;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1389
				} else {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1390
					// continue searching from the WHILE on
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1391
					fPosition= pos;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1392
					break;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1393
				}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1394
			case Symbols.TokenIDENT:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1395
				if (mayBeMethodBody == READ_PARENS)
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1396
					mayBeMethodBody= READ_IDENT;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1397
				break;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1398
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1399
			default:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1400
				// keep searching
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1401
			}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1402
		}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1403
	}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1404
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1405
	private int getBlockIndent(boolean isMethodBody, boolean isTypeBody) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1406
		if (isTypeBody) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1407
			return fPrefs.prefTypeIndent + fPrefs.prefAccessSpecifierIndent;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1408
		} else if (isMethodBody) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1409
			return fPrefs.prefMethodBodyIndent + (fPrefs.prefIndentBracesForMethods ? 1 : 0);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1410
		} else {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1411
			return fIndent;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1412
		}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1413
	}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1414
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1415
	/**
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1416
	 * Returns <code>true</code> if the colon at the current position is part of a conditional
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1417
	 * (ternary) expression, <code>false</code> otherwise.
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1418
	 *
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1419
	 * @return <code>true</code> if the colon at the current position is part of a conditional
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1420
	 */
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1421
	private boolean isConditional() {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1422
		while (true) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1423
			int previous= fToken;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1424
			nextToken();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1425
			switch (fToken) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1426
			// search for case labels, which consist of (possibly qualified) identifiers or numbers
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1427
			case Symbols.TokenIDENT:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1428
				if (previous == Symbols.TokenIDENT) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1429
					return false;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1430
				}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1431
				// fall thru
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1432
				continue;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1433
			case Symbols.TokenDOUBLECOLON:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1434
			case Symbols.TokenOTHER:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1435
				continue;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1436
				
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1437
			case Symbols.TokenQUESTIONMARK:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1438
				return true;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1439
				
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1440
			case Symbols.TokenSEMICOLON:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1441
			case Symbols.TokenLBRACE:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1442
			case Symbols.TokenRBRACE:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1443
			case Symbols.TokenCASE:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1444
			case Symbols.TokenDEFAULT:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1445
			case Symbols.TokenPUBLIC:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1446
			case Symbols.TokenPROTECTED:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1447
			case Symbols.TokenPRIVATE:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1448
			case Symbols.TokenCLASS:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1449
			case Symbols.TokenSTRUCT:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1450
			case Symbols.TokenUNION:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1451
				return false;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1452
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1453
			default:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1454
				return true;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1455
			}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1456
		}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1457
	}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1458
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1459
	/**
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1460
	 * Returns as a reference any previous <code>switch</code> labels (<code>case</code>
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1461
	 * or <code>default</code>) or the offset of the brace that scopes the switch
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1462
	 * statement. Sets <code>fIndent</code> to <code>prefCaseIndent</code> upon
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1463
	 * a match.
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1464
	 *
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1465
	 * @return the reference offset for a <code>switch</code> label
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1466
	 */
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1467
	private int matchCaseAlignment() {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1468
		while (true) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1469
			nextToken();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1470
			switch (fToken) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1471
			// invalid cases: another case label or an LBRACE must come before a case
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1472
			// -> bail out with the current position
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1473
			case Symbols.TokenLPAREN:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1474
			case Symbols.TokenLBRACKET:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1475
			case Symbols.TokenEOF:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1476
				return fPosition;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1477
				
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1478
			case Symbols.TokenSWITCH:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1479
				// start of switch statement
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1480
				fIndent= fPrefs.prefCaseIndent;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1481
				return fPosition;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1482
				
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1483
			case Symbols.TokenCASE:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1484
			case Symbols.TokenDEFAULT:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1485
				// align with previous label
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1486
				fIndent= 0;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1487
				return fPosition;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1488
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1489
			// scopes: skip them
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1490
			case Symbols.TokenRPAREN:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1491
			case Symbols.TokenRBRACKET:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1492
			case Symbols.TokenRBRACE:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1493
				skipScope();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1494
				break;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1495
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1496
			default:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1497
				// keep searching
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1498
				continue;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1499
			}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1500
		}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1501
	}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1502
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1503
	/**
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1504
	 * Returns as a reference any previous access specifiers (<code>public</code>,
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1505
	 * <code>protected</code> or <code>default</code>) or the offset of the brace that
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1506
	 * scopes the class body.
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1507
	 * Sets <code>fIndent</code> to <code>prefAccessSpecifierIndent</code> upon
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1508
	 * a match.
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1509
	 *
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1510
	 * @return the reference offset for an access specifier (public/protected/private)
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1511
	 */
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1512
	private int matchAccessSpecifierAlignment() {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1513
		while (true) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1514
			nextToken();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1515
			switch (fToken) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1516
			// invalid cases: another access specifier or an LBRACE must come before an access specifier
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1517
			// -> bail out with the current position
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1518
			case Symbols.TokenLPAREN:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1519
			case Symbols.TokenLBRACKET:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1520
			case Symbols.TokenEOF:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1521
				return fPosition;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1522
				
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1523
			case Symbols.TokenLBRACE:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1524
				// opening brace of class body
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1525
				int pos= fPosition;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1526
				int typeDeclPos= matchTypeDeclaration();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1527
				fIndent= fPrefs.prefAccessSpecifierIndent;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1528
				fExtraSpaces = fPrefs.prefAccessSpecifierExtraSpaces;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1529
				if (typeDeclPos != CHeuristicScanner.NOT_FOUND) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1530
					return typeDeclPos;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1531
				}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1532
				return pos;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1533
			case Symbols.TokenPUBLIC:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1534
			case Symbols.TokenPROTECTED:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1535
			case Symbols.TokenPRIVATE:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1536
				// align with previous access specifier
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1537
				fIndent= 0;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1538
				return fPosition;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1539
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1540
			// scopes: skip them
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1541
			case Symbols.TokenRPAREN:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1542
			case Symbols.TokenRBRACKET:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1543
			case Symbols.TokenRBRACE:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1544
				skipScope();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1545
				break;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1546
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1547
			default:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1548
				// keep searching
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1549
				continue;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1550
			}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1551
		}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1552
	}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1553
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1554
	/**
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1555
	 * Returns the reference position for a list element. The algorithm
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1556
	 * tries to match any previous indentation on the same list. If there is none,
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1557
	 * the reference position returned is determined depending on the type of list:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1558
	 * The indentation will either match the list scope introducer (e.g. for
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1559
	 * method declarations), so called deep indents, or simply increase the
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1560
	 * indentation by a number of standard indents. See also {@link #handleScopeIntroduction(int, boolean)}.
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1561
	 * @return the reference position for a list item: either a previous list item
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1562
	 * that has its own indentation, or the list introduction start.
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1563
	 */
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1564
	private int skipToPreviousListItemOrListStart() {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1565
		int startLine= fLine;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1566
		int startPosition= fPosition;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1567
		boolean seenEqual = fToken == Symbols.TokenEQUAL;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1568
		boolean seenShiftLeft = fToken == Symbols.TokenSHIFTLEFT;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1569
		boolean seenRightParen = fToken == Symbols.TokenRPAREN;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1570
		while (true) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1571
			nextToken();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1572
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1573
			// If any line item comes with its own indentation, adapt to it
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1574
			if (fLine < startLine) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1575
				try {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1576
					int lineOffset= fDocument.getLineOffset(startLine);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1577
					int bound= Math.min(fDocument.getLength(), startPosition + 1);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1578
					if ((fToken == Symbols.TokenSEMICOLON || fToken == Symbols.TokenRBRACE ||
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1579
							fToken == Symbols.TokenLBRACE && !looksLikeArrayInitializerIntro()) &&
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1580
							(seenEqual || seenShiftLeft || seenRightParen)) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1581
						fIndent = fPrefs.prefContinuationIndent;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1582
					} else {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1583
						fAlign= fScanner.findNonWhitespaceForwardInAnyPartition(lineOffset, bound);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1584
						// If the reference line starts with a colon, skip the colon.  
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1585
						if (peekToken(fAlign) == Symbols.TokenCOLON) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1586
							fAlign= fScanner.findNonWhitespaceForwardInAnyPartition(fAlign + 1, bound);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1587
						}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1588
					}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1589
				} catch (BadLocationException e) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1590
					// Ignore and return just the position
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1591
				}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1592
				return startPosition;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1593
			}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1594
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1595
			switch (fToken) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1596
			// scopes: skip them
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1597
			case Symbols.TokenRPAREN:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1598
				seenRightParen = true;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1599
				//$FALL-THROUGH$
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1600
			case Symbols.TokenRBRACKET:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1601
			case Symbols.TokenRBRACE:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1602
				skipScope();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1603
				break;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1604
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1605
			// scope introduction: special treat who special is
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1606
			case Symbols.TokenLPAREN:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1607
			case Symbols.TokenLBRACE:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1608
			case Symbols.TokenLBRACKET:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1609
				return handleScopeIntroduction(startPosition + 1, false);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1610
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1611
			case Symbols.TokenSEMICOLON:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1612
				return fPosition;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1613
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1614
			case Symbols.TokenQUESTIONMARK:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1615
				if (fPrefs.prefTernaryDeepAlign) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1616
					setFirstElementAlignment(fPosition - 1, fPosition + 1);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1617
				} else {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1618
					fIndent= fPrefs.prefTernaryIndent;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1619
				}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1620
				return fPosition;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1621
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1622
			case Symbols.TokenEQUAL:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1623
				seenEqual = true;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1624
				break;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1625
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1626
			case Symbols.TokenSHIFTLEFT:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1627
				seenShiftLeft = true;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1628
				break;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1629
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1630
			case Symbols.TokenEOF:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1631
				if (seenEqual || seenShiftLeft || seenRightParen) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1632
					fIndent = fPrefs.prefContinuationIndent;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1633
				}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1634
				return 0;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1635
			}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1636
		}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1637
	}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1638
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1639
	/**
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1640
	 * Skips a scope and positions the cursor (<code>fPosition</code>) on the
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1641
	 * token that opens the scope. Returns <code>true</code> if a matching peer
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1642
	 * could be found, <code>false</code> otherwise. The current token when calling
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1643
	 * must be one out of <code>Symbols.TokenRPAREN</code>, <code>Symbols.TokenRBRACE</code>,
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1644
	 * and <code>Symbols.TokenRBRACKET</code>.
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1645
	 *
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1646
	 * @return <code>true</code> if a matching peer was found, <code>false</code> otherwise
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1647
	 */
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1648
	private boolean skipScope() {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1649
		switch (fToken) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1650
		case Symbols.TokenRPAREN:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1651
			return skipScope(Symbols.TokenLPAREN, Symbols.TokenRPAREN);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1652
		case Symbols.TokenRBRACKET:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1653
			return skipScope(Symbols.TokenLBRACKET, Symbols.TokenRBRACKET);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1654
		case Symbols.TokenRBRACE:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1655
			return skipScope(Symbols.TokenLBRACE, Symbols.TokenRBRACE);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1656
		case Symbols.TokenGREATERTHAN:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1657
			if (!fPrefs.prefHasTemplates)
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1658
				return false;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1659
			int storedPosition= fPosition;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1660
			int storedToken= fToken;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1661
			nextToken();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1662
			switch (fToken) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1663
				case Symbols.TokenIDENT:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1664
					if (skipScope(Symbols.TokenLESSTHAN, Symbols.TokenGREATERTHAN))
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1665
						return true;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1666
					break;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1667
				case Symbols.TokenQUESTIONMARK:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1668
				case Symbols.TokenGREATERTHAN:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1669
					if (skipScope(Symbols.TokenLESSTHAN, Symbols.TokenGREATERTHAN))
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1670
						return true;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1671
					break;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1672
			}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1673
			// <> are harder to detect - restore the position if we fail
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1674
			fPosition= storedPosition;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1675
			fToken= storedToken;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1676
			return false;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1677
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1678
		default:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1679
			 // programming error
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1680
			Assert.isTrue(false);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1681
			return false;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1682
		}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1683
	}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1684
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1685
	/**
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1686
	 * Returns the contents of the current token.
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1687
	 *
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1688
	 * @return the contents of the current token
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1689
	 */
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1690
	private CharSequence getTokenContent() {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1691
		return new DocumentCharacterIterator(fDocument, fPosition, fPreviousPos);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1692
	}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1693
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1694
	/**
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1695
	 * Handles the introduction of a new scope. The current token must be one out
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1696
	 * of <code>Symbols.TokenLPAREN</code>, <code>Symbols.TokenLBRACE</code>,
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1697
	 * and <code>Symbols.TokenLBRACKET</code>. Returns as the reference position
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1698
	 * either the token introducing the scope or - if available - the first
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1699
	 * token after that.
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1700
	 *
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1701
	 * <p>Depending on the type of scope introduction, the indentation will align
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1702
	 * (deep indenting) with the reference position (<code>fAlign</code> will be
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1703
	 * set to the reference position) or <code>fIndent</code> will be set to
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1704
	 * the number of indentation units.
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1705
	 * </p>
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1706
	 *
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1707
	 * @param bound the bound for the search for the first token after the scope
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1708
	 * introduction.
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1709
	 * @param firstToken <code>true</code> if we are dealing with the first token after
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1710
	 * the opening parenthesis.
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1711
	 * @return the indent
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1712
	 */
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1713
	private int handleScopeIntroduction(int bound, boolean firstToken) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1714
		int pos= fPosition; // store
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1715
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1716
		switch (fToken) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1717
		// scope introduction: special treat who special is
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1718
		case Symbols.TokenLPAREN:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1719
			// special: method declaration deep indentation
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1720
			if (looksLikeMethodDecl()) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1721
				if (firstToken ? fPrefs.prefMethodDeclFirstParameterDeepIndent : fPrefs.prefMethodDeclDeepIndent) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1722
					return setFirstElementAlignment(pos, bound);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1723
				} else {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1724
					fIndent= fPrefs.prefMethodDeclIndent;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1725
					return pos;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1726
				}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1727
			} else {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1728
				fPosition= pos;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1729
				if (looksLikeMethodCall()) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1730
					if (firstToken ? fPrefs.prefMethodCallFirstParameterDeepIndent : fPrefs.prefMethodCallDeepIndent) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1731
						return setFirstElementAlignment(pos, bound);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1732
					} else {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1733
						fIndent= fPrefs.prefMethodCallIndent;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1734
						return pos;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1735
					}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1736
				} else if (fPrefs.prefParenthesisDeepIndent) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1737
					return setFirstElementAlignment(pos, bound);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1738
				}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1739
			}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1740
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1741
			// normal: return the parenthesis as reference
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1742
			fIndent= fPrefs.prefParenthesisIndent;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1743
			return pos;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1744
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1745
		case Symbols.TokenLBRACE:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1746
			final boolean looksLikeArrayInitializerIntro= looksLikeArrayInitializerIntro();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1747
			// special: array initializer
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1748
			if (looksLikeArrayInitializerIntro) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1749
				if (fPrefs.prefArrayDeepIndent)
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1750
					return setFirstElementAlignment(pos, bound);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1751
				else
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1752
					fIndent= fPrefs.prefArrayIndent;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1753
			} else if (isNamespace()) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1754
				fIndent= fPrefs.prefNamespaceBodyIndent;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1755
			} else {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1756
				int typeDeclPos = matchTypeDeclaration();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1757
				if (typeDeclPos == CHeuristicScanner.NOT_FOUND) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1758
					fIndent= fPrefs.prefBlockIndent;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1759
				} else {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1760
					fIndent= fPrefs.prefAccessSpecifierIndent + fPrefs.prefTypeIndent;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1761
				}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1762
			}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1763
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1764
			// normal: skip to the statement start before the scope introducer
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1765
			// opening braces are often on differently ending indents than e.g. a method definition
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1766
			if (!looksLikeArrayInitializerIntro) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1767
				fPosition= pos; // restore
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1768
				return skipToStatementStart(true, true); // set to true to match the first if
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1769
			} else {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1770
				return pos;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1771
			}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1772
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1773
		case Symbols.TokenLBRACKET:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1774
			// special: method declaration deep indentation
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1775
			if (fPrefs.prefArrayDimensionsDeepIndent) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1776
				return setFirstElementAlignment(pos, bound);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1777
			}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1778
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1779
			// normal: return the bracket as reference
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1780
			fIndent= fPrefs.prefBracketIndent;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1781
			return pos; // restore
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1782
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1783
		default:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1784
			// programming error
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1785
			Assert.isTrue(false);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1786
			return -1; // dummy
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1787
		}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1788
	}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1789
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1790
	/**
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1791
	 * Sets the deep indent offset (<code>fAlign</code>) to either the offset
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1792
	 * right after <code>scopeIntroducerOffset</code> or - if available - the
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1793
	 * first C token after <code>scopeIntroducerOffset</code>, but before
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1794
	 * <code>bound</code>.
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1795
	 *
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1796
	 * @param scopeIntroducerOffset the offset of the scope introducer
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1797
	 * @param bound the bound for the search for another element
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1798
	 * @return the reference position
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1799
	 */
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1800
	private int setFirstElementAlignment(int scopeIntroducerOffset, int bound) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1801
		int firstPossible= scopeIntroducerOffset + 1; // align with the first position after the scope intro
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1802
		fAlign= fScanner.findNonWhitespaceForwardInAnyPartition(firstPossible, bound);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1803
		if (fAlign == CHeuristicScanner.NOT_FOUND) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1804
			fAlign= firstPossible;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1805
		} else {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1806
			try {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1807
				IRegion lineRegion = fDocument.getLineInformationOfOffset(scopeIntroducerOffset);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1808
				if (fAlign > lineRegion.getOffset() + lineRegion.getLength()) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1809
					fAlign= firstPossible; 
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1810
				}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1811
			} catch (BadLocationException e) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1812
				// Ignore.
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1813
			}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1814
		}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1815
		return fAlign;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1816
	}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1817
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1818
	/**
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1819
	 * Returns <code>true</code> if the next token received after calling
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1820
	 * <code>nextToken</code> is either an equal sign, an opening brace,
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1821
	 * a comma or an array designator ('[]').
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1822
	 *
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1823
	 * @return <code>true</code> if the next elements look like the start of an array definition
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1824
	 */
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1825
	private boolean looksLikeArrayInitializerIntro() {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1826
		int pos= fPosition;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1827
		nextToken();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1828
		switch (fToken) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1829
		case Symbols.TokenEQUAL:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1830
			return true;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1831
		case Symbols.TokenRBRACKET:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1832
			return skipBrackets();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1833
		case Symbols.TokenLBRACE:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1834
			if (looksLikeArrayInitializerIntro()) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1835
				fPosition= pos;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1836
				return true;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1837
			}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1838
			return false;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1839
		case Symbols.TokenCOMMA:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1840
			fPosition= pos;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1841
			return true;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1842
		}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1843
		return false;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1844
	}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1845
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1846
	/**
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1847
	 * Returns <code>true</code> if the the current token is "namespace", or the current token
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1848
	 * is an identifier and the previous token is "namespace".
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1849
	 *
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1850
	 * @return <code>true</code> if the next elements look like the start of a namespace declaration.
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1851
	 */
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1852
	private boolean isNamespace() {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1853
		int pos = fPosition;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1854
		if (fToken == Symbols.TokenNAMESPACE) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1855
			return true;		// Anonymous namespace
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1856
		} else if (fToken == Symbols.TokenIDENT) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1857
			nextToken();		// Get previous token
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1858
			if (fToken == Symbols.TokenNAMESPACE) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1859
				return true;	// Named namespace
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1860
			}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1861
		}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1862
		fPosition = pos;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1863
		return false;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1864
	}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1865
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1866
	/**
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1867
	 * Skips over the next <code>if</code> keyword. The current token when calling
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1868
	 * this method must be an <code>else</code> keyword. Returns <code>true</code>
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1869
	 * if a matching <code>if</code> could be found, <code>false</code> otherwise.
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1870
	 * The cursor (<code>fPosition</code>) is set to the offset of the <code>if</code>
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1871
	 * token.
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1872
	 *
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1873
	 * @return <code>true</code> if a matching <code>if</code> token was found, <code>false</code> otherwise
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1874
	 */
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1875
	private boolean skipNextIF() {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1876
		Assert.isTrue(fToken == Symbols.TokenELSE);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1877
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1878
		while (true) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1879
			nextToken();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1880
			switch (fToken) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1881
			// scopes: skip them
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1882
			case Symbols.TokenRPAREN:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1883
			case Symbols.TokenRBRACKET:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1884
			case Symbols.TokenRBRACE:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1885
				skipScope();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1886
				break;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1887
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1888
			case Symbols.TokenIF:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1889
				// found it, return
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1890
				return true;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1891
			case Symbols.TokenELSE:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1892
				// recursively skip else-if blocks
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1893
				skipNextIF();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1894
				break;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1895
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1896
			// shortcut scope starts
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1897
			case Symbols.TokenLPAREN:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1898
			case Symbols.TokenLBRACE:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1899
			case Symbols.TokenLBRACKET:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1900
			case Symbols.TokenEOF:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1901
				return false;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1902
			}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1903
		}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1904
	}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1905
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1906
	/**
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1907
	 * while(condition); is ambiguous when parsed backwardly, as it is a valid
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1908
	 * statement by its own, so we have to check whether there is a matching
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1909
	 * do. A <code>do</code> can either be separated from the while by a
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1910
	 * block, or by a single statement, which limits our search distance.
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1911
	 *
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1912
	 * @return <code>true</code> if the <code>while</code> currently in
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1913
	 *         <code>fToken</code> has a matching <code>do</code>.
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1914
	 */
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1915
	private boolean hasMatchingDo() {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1916
		Assert.isTrue(fToken == Symbols.TokenWHILE);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1917
		nextToken();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1918
		switch (fToken) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1919
		case Symbols.TokenRBRACE:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1920
			skipScope(); // and fall thru
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1921
			skipToStatementStart(false, false);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1922
			return fToken == Symbols.TokenDO;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1923
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1924
		case Symbols.TokenSEMICOLON:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1925
			skipToStatementStart(false, false);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1926
			return fToken == Symbols.TokenDO;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1927
		}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1928
		return false;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1929
	}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1930
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1931
	/**
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1932
	 * Skips pointer operators if the current token is a pointer operator.
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1933
	 *
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1934
	 * @return <code>true</code> if a <code>*</code> or <code>&amp;</code> could be scanned, the
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1935
	 *         current token is left at the operator.
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1936
	 */
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1937
	private boolean skipPointerOperators() {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1938
		if (fToken == Symbols.TokenOTHER) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1939
			CharSequence token= getTokenContent();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1940
			if (token.length() == 1 && token.charAt(0) == '*' || token.charAt(0) == '&') {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1941
				return true;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1942
			}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1943
		} else if (fToken == Symbols.TokenCONST) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1944
			return true;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1945
		}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1946
		return false;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1947
	}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1948
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1949
	/**
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1950
	 * Skips brackets if the current token is a RBRACKET. There can be nothing
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1951
	 * but whitespace in between, this is only to be used for <code>[]</code> elements.
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1952
	 *
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1953
	 * @return <code>true</code> if a <code>[]</code> could be scanned, the
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1954
	 *         current token is left at the LBRACKET.
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1955
	 */
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1956
	private boolean skipBrackets() {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1957
		if (fToken == Symbols.TokenRBRACKET) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1958
			nextToken();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1959
			if (fToken == Symbols.TokenLBRACKET) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1960
				return true;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1961
			}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1962
		}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1963
		return false;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1964
	}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1965
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1966
	/**
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1967
	 * Skips scope qualifiers of identifiers.
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1968
	 * 
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1969
	 * @return <code>true</code> if a qualifier was encountered, the last token
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1970
	 *         will be an IDENT.
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1971
	 */
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1972
	private boolean skipQualifiers() {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1973
		if (fToken == Symbols.TokenDOUBLECOLON) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1974
			nextToken();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1975
			if (fToken == Symbols.TokenIDENT) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1976
				return true;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1977
			}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1978
		}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1979
		return false;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1980
	}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1981
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1982
	/**
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1983
	 * Reads the next token in backward direction from the heuristic scanner
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1984
	 * and sets the fields <code>fToken, fPreviousPosition</code> and <code>fPosition</code>
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1985
	 * accordingly.
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1986
	 */
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1987
	private void nextToken() {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1988
		nextToken(fPosition);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1989
	}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1990
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1991
	/**
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1992
	 * Reads the next token in backward direction of <code>start</code> from
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1993
	 * the heuristic scanner and sets the fields <code>fToken, fPreviousPosition</code>
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1994
	 * and <code>fPosition</code> accordingly.
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1995
	 *
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1996
	 * @param start the start offset from which to scan backwards
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1997
	 */
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1998
	private void nextToken(int start) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  1999
		fToken= fScanner.previousToken(start - 1, CHeuristicScanner.UNBOUND);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2000
		fPreviousPos= start;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2001
		fPosition= fScanner.getPosition() + 1;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2002
		try {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2003
			fLine= fDocument.getLineOfOffset(fPosition);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2004
		} catch (BadLocationException e) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2005
			fLine= -1;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2006
		}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2007
	}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2008
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2009
	/**
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2010
	 * Reads the next token in backward direction from the heuristic scanner
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2011
	 * and returns that token without changing the current position.
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2012
	 */
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2013
	private int peekToken() {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2014
		return fScanner.previousToken(fPosition - 1, CHeuristicScanner.UNBOUND);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2015
	}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2016
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2017
	/**
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2018
	 * Returns <code>true</code> if the current tokens look like a method
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2019
	 * declaration header (i.e. only the return type and method name). The
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2020
	 * heuristic calls <code>nextToken</code> and expects an identifier
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2021
	 * (method name) and an optional return type declaration.
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2022
	 *
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2023
	 * @return <code>true</code> if the current position looks like a method
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2024
	 *         declaration header.
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2025
	 */
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2026
	private boolean looksLikeMethodDecl() {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2027
		nextToken();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2028
		switch (fToken) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2029
		case Symbols.TokenIDENT: // method name
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2030
			int pos= fPosition;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2031
			nextToken();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2032
			// check destructor tilde
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2033
			if (fToken == Symbols.TokenTILDE) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2034
				return true;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2035
			}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2036
			if (skipQualifiers()) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2037
				return true;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2038
			}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2039
			// optional brackets for array valued return types
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2040
			while (skipBrackets()) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2041
				nextToken();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2042
			}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2043
			while (skipPointerOperators()) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2044
				nextToken();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2045
			}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2046
			switch (fToken) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2047
			case Symbols.TokenIDENT:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2048
				return true;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2049
			case Symbols.TokenSEMICOLON:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2050
			case Symbols.TokenRBRACE:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2051
				fPosition= pos;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2052
				return true;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2053
			case Symbols.TokenLBRACE:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2054
				if (fScanner.looksLikeCompositeTypeDefinitionBackward(fPosition, CHeuristicScanner.UNBOUND)) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2055
					fPosition= pos;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2056
					return true;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2057
				}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2058
				break;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2059
			case Symbols.TokenCOLON:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2060
				nextToken();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2061
				switch (fToken) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2062
				case Symbols.TokenPUBLIC:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2063
				case Symbols.TokenPROTECTED:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2064
				case Symbols.TokenPRIVATE:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2065
					fPosition= pos;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2066
					return true;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2067
				case Symbols.TokenRPAREN:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2068
					// constructor initializer
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2069
					if (skipScope()) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2070
						nextToken();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2071
						// optional throw
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2072
						if (fToken == Symbols.TokenTHROW) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2073
							nextToken();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2074
							if (fToken != Symbols.TokenRPAREN || !skipScope()) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2075
								return false;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2076
							}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2077
						}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2078
						return looksLikeMethodDecl();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2079
					}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2080
					break;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2081
				}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2082
			}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2083
			break;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2084
		case Symbols.TokenARROW:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2085
		case Symbols.TokenCOMMA:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2086
		case Symbols.TokenEQUAL:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2087
		case Symbols.TokenGREATERTHAN:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2088
		case Symbols.TokenLESSTHAN:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2089
		case Symbols.TokenMINUS:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2090
		case Symbols.TokenSHIFTRIGHT:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2091
		case Symbols.TokenSHIFTLEFT:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2092
		case Symbols.TokenDELETE:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2093
		case Symbols.TokenNEW:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2094
			nextToken();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2095
			return fToken == Symbols.TokenOPERATOR;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2096
		case Symbols.TokenOTHER:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2097
			if (getTokenContent().length() == 1) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2098
				nextToken();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2099
				if (fToken == Symbols.TokenOPERATOR)
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2100
					return true;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2101
			}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2102
			if (getTokenContent().length() == 1) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2103
				nextToken();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2104
				if (fToken == Symbols.TokenOPERATOR)
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2105
					return true;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2106
			}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2107
		}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2108
		return false;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2109
	}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2110
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2111
	/**
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2112
	 * Returns <code>true</code> if the current tokens look like an anonymous type declaration
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2113
	 * header (i.e. a type name (potentially qualified) and a new keyword). The heuristic calls
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2114
	 * <code>nextToken</code> and expects a possibly qualified identifier (type name) and a new
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2115
	 * keyword
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2116
	 * 
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2117
	 * @return <code>true</code> if the current position looks like a anonymous type declaration
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2118
	 *         header.
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2119
	 */
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2120
	private boolean looksLikeAnonymousTypeDecl() {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2121
		nextToken();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2122
		if (fToken == Symbols.TokenIDENT) { // type name
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2123
			nextToken();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2124
			while (fToken == Symbols.TokenOTHER) { // dot of qualification
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2125
				nextToken();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2126
				if (fToken != Symbols.TokenIDENT) // qualificating name
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2127
					return false;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2128
				nextToken();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2129
			}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2130
			return fToken == Symbols.TokenNEW;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2131
		}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2132
		return false;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2133
	}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2134
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2135
	/**
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2136
	 * Returns <code>true</code> if the current tokens look like a method
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2137
	 * call header (i.e. an identifier as opposed to a keyword taking parenthesized
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2138
	 * parameters such as <code>if</code>).
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2139
	 * <p>The heuristic calls <code>nextToken</code> and expects an identifier
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2140
	 * (method name).
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2141
	 *
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2142
	 * @return <code>true</code> if the current position looks like a method call
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2143
	 *         header.
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2144
	 */
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2145
	private boolean looksLikeMethodCall() {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2146
		// TODO add awareness for constructor calls with templates: new complex<float>()
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2147
		nextToken();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2148
		return fToken == Symbols.TokenIDENT; // method name
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2149
	}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2150
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2151
	/**
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2152
	 * Scans tokens for the matching opening peer. The internal cursor
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2153
	 * (<code>fPosition</code>) is set to the offset of the opening peer if found.
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2154
	 *
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2155
	 * @param openToken the opening peer token
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2156
	 * @param closeToken the closing peer token
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2157
	 * @return <code>true</code> if a matching token was found, <code>false</code>
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2158
	 *         otherwise
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2159
	 */
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2160
	private boolean skipScope(int openToken, int closeToken) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2161
		int depth= 1;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2162
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2163
		while (true) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2164
			nextToken();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2165
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2166
			if (fToken == closeToken) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2167
				depth++;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2168
			} else if (fToken == openToken) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2169
				depth--;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2170
				if (depth == 0)
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2171
					return true;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2172
			} else if (fToken == Symbols.TokenEOF) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2173
				return false;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2174
			}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2175
		}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2176
	}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
  2177
}