Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeff Johnston2013-07-05 15:47:47 +0000
committerRoland Grunberg2013-07-16 15:12:07 +0000
commiteb89adf93e110820907276acac9ffb72b80aa8ee (patch)
treed4f8e0a4d72978c4d75c33bc98dbd92260938528 /systemtap
parentcac6bb9eb77a7329e78b43161438475723075127 (diff)
downloadorg.eclipse.linuxtools-eb89adf93e110820907276acac9ffb72b80aa8ee.tar.gz
org.eclipse.linuxtools-eb89adf93e110820907276acac9ffb72b80aa8ee.tar.xz
org.eclipse.linuxtools-eb89adf93e110820907276acac9ffb72b80aa8ee.zip
Bug 401545 - Add formatting to SystemTap Editor
- add indent strategy into SystemTap editor based on C/C++ indenter - add support for overwriting auto-added characters such as end-bracket, quote, and right square-bracket - simplify base SystemTap partitioner to ignore strings and probes - add additional partitioner with old partitioner logic - fix completion proposals to look for offsets that start a new partition after a default partition - add formatter test - fix completion tests to get proper partitioning Change-Id: Icb1ae2aac9d25d24685204098cf24f11f11c749b Reviewed-on: https://git.eclipse.org/r/14523 Tested-by: Hudson CI Reviewed-by: Camilo Bernal <cabernal@redhat.com> IP-Clean: Camilo Bernal <cabernal@redhat.com> Tested-by: Camilo Bernal <cabernal@redhat.com> Reviewed-by: Roland Grunberg <rgrunber@redhat.com> IP-Clean: Roland Grunberg <rgrunber@redhat.com> Tested-by: Roland Grunberg <rgrunber@redhat.com>
Diffstat (limited to 'systemtap')
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide.tests/src/org/eclipse/linuxtools/systemtap/ui/ide/test/AllTests.java3
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide.tests/src/org/eclipse/linuxtools/systemtap/ui/ide/test/editors/stp/AbstractAutoEditTest.java257
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide.tests/src/org/eclipse/linuxtools/systemtap/ui/ide/test/editors/stp/STPCompletionProcessorTest.java17
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide.tests/src/org/eclipse/linuxtools/systemtap/ui/ide/test/editors/stp/STPFormattingTest.java424
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide.tests/src/org/eclipse/linuxtools/systemtap/ui/ide/test/editors/stp/STPToggleCommentTest.java21
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/IDEPlugin.java63
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/actions/ToggleCommentHandler.java4
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/AbortFormatting.java32
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/AlignmentException.java53
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/CharArrayUtils.java374
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/CodeFormatterUtil.java27
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/DocumentCharacterIterator.java246
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/IndentUtil.java655
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/OptimizedReplaceEdit.java30
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPAlignment.java516
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPAutoEditStrategy.java1050
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPCompletionProcessor.java47
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPConfiguration.java19
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPDefaultCodeFormatterConstants.java2620
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPDefaultCodeFormatterOptions.java1912
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPDocumentProvider.java11
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPHeuristicScanner.java1241
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPIndenter.java2349
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPLocation.java57
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPPartitionScanner.java14
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPProbeScanner.java56
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPScribe.java2151
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPSymbols.java79
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/Scanner.java224
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/ScannerContext.java85
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/SimpleScanner.java963
-rw-r--r--systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/Token.java509
32 files changed, 16053 insertions, 56 deletions
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide.tests/src/org/eclipse/linuxtools/systemtap/ui/ide/test/AllTests.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide.tests/src/org/eclipse/linuxtools/systemtap/ui/ide/test/AllTests.java
index b70d59af37..b6c254c8a2 100644
--- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide.tests/src/org/eclipse/linuxtools/systemtap/ui/ide/test/AllTests.java
+++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide.tests/src/org/eclipse/linuxtools/systemtap/ui/ide/test/AllTests.java
@@ -12,6 +12,7 @@
package org.eclipse.linuxtools.systemtap.ui.ide.test;
import org.eclipse.linuxtools.systemtap.ui.ide.test.editors.stp.STPCompletionProcessorTest;
+import org.eclipse.linuxtools.systemtap.ui.ide.test.editors.stp.STPFormattingTest;
import org.eclipse.linuxtools.systemtap.ui.ide.test.editors.stp.STPToggleCommentTest;
import org.eclipse.linuxtools.systemtap.ui.ide.test.structures.StapErrorParserTest;
import org.eclipse.linuxtools.systemtap.ui.ide.test.structures.TreeSettingsTest;
@@ -24,6 +25,6 @@ import org.junit.runners.Suite.SuiteClasses;
@SuiteClasses({ StapErrorParserTest.class, TreeSettingsTest.class,
STPCompletionProcessorTest.class, STPToggleCommentTest.class,
TestCreateSystemtapScript.class, ConditionalExpressionValidatorTest.class,
- DirectoryValidatorTest.class })
+ DirectoryValidatorTest.class, STPFormattingTest.class })
public class AllTests {
}
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide.tests/src/org/eclipse/linuxtools/systemtap/ui/ide/test/editors/stp/AbstractAutoEditTest.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide.tests/src/org/eclipse/linuxtools/systemtap/ui/ide/test/editors/stp/AbstractAutoEditTest.java
new file mode 100644
index 0000000000..b131c70e8d
--- /dev/null
+++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide.tests/src/org/eclipse/linuxtools/systemtap/ui/ide/test/editors/stp/AbstractAutoEditTest.java
@@ -0,0 +1,257 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2008 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Anton Leherbauer (Wind River Systems) - initial API and implementation
+ * Sergey Prigogin (Google)
+ * Andrew Ferguson (Symbian)
+ * Andrew Gvozdev
+ *******************************************************************************/
+package org.eclipse.linuxtools.systemtap.ui.ide.test.editors.stp;
+
+import static org.junit.Assert.fail;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.DocumentCommand;
+import org.eclipse.jface.text.IAutoEditStrategy;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.TextUtilities;
+import org.eclipse.linuxtools.systemtap.ui.tests.SystemtapTest;
+
+/**
+ * IAutoEditStrategy related tests
+ */
+public class AbstractAutoEditTest extends SystemtapTest {
+
+ private String name;
+
+ protected AbstractAutoEditTest(String name) {
+ super();
+ this.name = name;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Helper class to test the auto-edit strategies on a document.
+ * Split out from CAutoIndentTest.
+ */
+ protected static class AutoEditTester {
+ private IAutoEditStrategy tabsToSpacesConverter;
+ private Map<String, IAutoEditStrategy> fStrategyMap = new HashMap<String, IAutoEditStrategy>();
+ IDocument fDoc;
+ private String fPartitioning;
+ private int fCaretOffset;
+
+ public AutoEditTester(IDocument doc, String partitioning) {
+ super();
+ fDoc = doc;
+ fPartitioning = partitioning;
+ }
+
+ public void setTabsToSpacesConverter(IAutoEditStrategy converter) {
+ tabsToSpacesConverter = converter;
+ }
+
+ public void setAutoEditStrategy(String contentType, IAutoEditStrategy aes) {
+ fStrategyMap.put(contentType, aes);
+ }
+
+ public IAutoEditStrategy getAutoEditStrategy(String contentType) {
+ return fStrategyMap.get(contentType);
+ }
+
+ /**
+ * Empties the document, and returns the caret to the origin (0,0)
+ * @return <code>this</code> for method chaining
+ */
+ public AutoEditTester reset() {
+ try {
+ goTo(0,0);
+ fDoc.set("");
+ } catch(BadLocationException ble) {
+ fail(ble.getMessage());
+ }
+ return this;
+ }
+
+ public void type(String text) throws BadLocationException {
+ for (int i = 0; i < text.length(); ++i) {
+ type(text.charAt(i));
+ }
+ }
+
+ public void type(char c) throws BadLocationException {
+ TestDocumentCommand command = new TestDocumentCommand(fCaretOffset, 0, new String(new char[] { c }));
+ customizeDocumentCommand(command);
+ fCaretOffset = command.exec(fDoc);
+ }
+
+ private void customizeDocumentCommand(TestDocumentCommand command) throws BadLocationException {
+ if (tabsToSpacesConverter != null) {
+ tabsToSpacesConverter.customizeDocumentCommand(fDoc, command);
+ }
+ IAutoEditStrategy aes = getAutoEditStrategy(getContentType(command.offset));
+ if (aes != null) {
+ aes.customizeDocumentCommand(fDoc, command);
+ }
+ }
+
+ public void type(int offset, String text) throws BadLocationException {
+ fCaretOffset = offset;
+ type(text);
+ }
+
+ public void type(int offset, char c) throws BadLocationException {
+ fCaretOffset = offset;
+ type(c);
+ }
+
+ public void paste(String text) throws BadLocationException {
+ TestDocumentCommand command = new TestDocumentCommand(fCaretOffset, 0, text);
+ customizeDocumentCommand(command);
+ fCaretOffset = command.exec(fDoc);
+ }
+
+ public void paste(int offset, String text) throws BadLocationException {
+ fCaretOffset = offset;
+ paste(text);
+ }
+
+ public void backspace(int n) throws BadLocationException {
+ for (int i = 0; i < n; ++i) {
+ backspace();
+ }
+ }
+
+ public void backspace() throws BadLocationException {
+ TestDocumentCommand command = new TestDocumentCommand(fCaretOffset - 1, 1, ""); //$NON-NLS-1$
+ customizeDocumentCommand(command);
+ fCaretOffset = command.exec(fDoc);
+ }
+
+ public int getCaretOffset() {
+ return fCaretOffset;
+ }
+
+ public int setCaretOffset(int offset) {
+ fCaretOffset = offset;
+ if (fCaretOffset < 0)
+ fCaretOffset = 0;
+ else if (fCaretOffset > fDoc.getLength())
+ fCaretOffset = fDoc.getLength();
+ return fCaretOffset;
+ }
+
+ /**
+ * Moves caret right or left by the given number of characters.
+ *
+ * @param shift Move distance.
+ * @return New caret offset.
+ */
+ public int moveCaret(int shift) {
+ return setCaretOffset(fCaretOffset + shift);
+ }
+
+ public int goTo(int line) throws BadLocationException {
+ fCaretOffset = fDoc.getLineOffset(line);
+ return fCaretOffset;
+ }
+
+ public int goTo(int line, int column) throws BadLocationException {
+ if (column < 0 || column > fDoc.getLineLength(line)) {
+ throw new BadLocationException("No column " + column + " in line " + line); //$NON-NLS-1$ $NON-NLS-2$
+ }
+ fCaretOffset = fDoc.getLineOffset(line) + column;
+ return fCaretOffset;
+ }
+
+ public int getCaretLine() throws BadLocationException {
+ return fDoc.getLineOfOffset(fCaretOffset);
+ }
+
+ public int getCaretColumn() throws BadLocationException {
+ IRegion region = fDoc.getLineInformationOfOffset(fCaretOffset);
+ return fCaretOffset - region.getOffset();
+ }
+
+ public char getChar() throws BadLocationException {
+ return getChar(0);
+ }
+
+ public char getChar(int i) throws BadLocationException {
+ return fDoc.getChar(fCaretOffset+i);
+ }
+
+ public String getLine() throws BadLocationException {
+ return getLine(0);
+ }
+
+ public String getLine(int i) throws BadLocationException {
+ IRegion region = fDoc.getLineInformation(getCaretLine() + i);
+ return fDoc.get(region.getOffset(), region.getLength());
+ }
+
+ public String getContentType(int offset) throws BadLocationException {
+ return TextUtilities.getContentType(fDoc, fPartitioning, offset, false); //TRUE??
+ }
+ }
+
+ /**
+ * A DocumentCommand with public constructor and exec method.
+ */
+ protected static class TestDocumentCommand extends DocumentCommand {
+
+ public TestDocumentCommand(int offset, int length, String text) {
+ super();
+ doit = true;
+ this.text = text;
+
+ this.offset = offset;
+ this.length = length;
+
+ owner = null;
+ caretOffset = -1;
+ }
+
+ /**
+ * @param doc
+ * @return the new caret position.
+ * @throws BadLocationException
+ */
+ public int exec(IDocument doc) throws BadLocationException {
+ doc.replace(offset, length, text);
+ return caretOffset != -1 ?
+ caretOffset :
+ offset + (text == null ? 0 : text.length());
+ }
+ }
+
+// protected CharSequence[] getTestContents() {
+// try {
+// return TestSourceReader.getContentsForTest(CTestPlugin.getDefault().getBundle(), "ui", this.getClass(), getName(), 2);
+// } catch (IOException e) {
+// fail(e.getMessage());
+// }
+// return null;
+// }
+//
+// protected CharSequence[] getTestContents1() {
+// try {
+// return TestSourceReader.getContentsForTest(CTestPlugin.getDefault().getBundle(), "ui", this.getClass(), getName(), 1);
+// } catch (IOException e) {
+// fail(e.getMessage());
+// }
+// return null;
+// }
+}
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide.tests/src/org/eclipse/linuxtools/systemtap/ui/ide/test/editors/stp/STPCompletionProcessorTest.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide.tests/src/org/eclipse/linuxtools/systemtap/ui/ide/test/editors/stp/STPCompletionProcessorTest.java
index f558b30553..485841e9dc 100644
--- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide.tests/src/org/eclipse/linuxtools/systemtap/ui/ide/test/editors/stp/STPCompletionProcessorTest.java
+++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide.tests/src/org/eclipse/linuxtools/systemtap/ui/ide/test/editors/stp/STPCompletionProcessorTest.java
@@ -78,14 +78,17 @@ public class STPCompletionProcessorTest extends SystemtapTest{
@Test
public void testGlobalCompletion() {
- Document testDocument = new Document(TEST_STP_SCRIPT);
+ MockSTPDocumentProvider provider = new MockSTPDocumentProvider(new Document(TEST_STP_SCRIPT));
+ IDocument testDocument = provider.createDocument(null);
int offset = TEST_STP_SCRIPT.indexOf("//marker1");
STPCompletionProcessor completionProcessor = new STPCompletionProcessor();
+ completionProcessor.waitForInitialization();
ICompletionProposal[] proposals = completionProcessor
.computeCompletionProposals(testDocument,
offset);
+ printProposals(proposals);
assertTrue(proposalsContain(proposals, "probe "));
assertTrue(proposalsContain(proposals, "global "));
assertTrue(proposalsContain(proposals, "function "));
@@ -201,7 +204,8 @@ public class STPCompletionProcessorTest extends SystemtapTest{
}
private ICompletionProposal[] getCompletionsForPrefix(String prefix) throws BadLocationException{
- Document testDocument = new Document(TEST_STP_SCRIPT);
+ MockSTPDocumentProvider provider = new MockSTPDocumentProvider(new Document(TEST_STP_SCRIPT));
+ IDocument testDocument = provider.createDocument(null);
int offset = TEST_STP_SCRIPT.indexOf("//marker1");
testDocument.replace(offset, 0, prefix);
offset += prefix.length();
@@ -209,6 +213,8 @@ public class STPCompletionProcessorTest extends SystemtapTest{
STPCompletionProcessor completionProcessor = new STPCompletionProcessor();
completionProcessor.waitForInitialization();
+ System.out.println(testDocument.get());
+
ICompletionProposal[] proposals = completionProcessor
.computeCompletionProposals(testDocument,
offset);
@@ -248,5 +254,10 @@ public class STPCompletionProcessorTest extends SystemtapTest{
}
return false;
}
-
+
+ private void printProposals(ICompletionProposal[] proposals){
+ for (ICompletionProposal p : proposals) {
+ System.out.println(p.getDisplayString());
+ }
+ }
}
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide.tests/src/org/eclipse/linuxtools/systemtap/ui/ide/test/editors/stp/STPFormattingTest.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide.tests/src/org/eclipse/linuxtools/systemtap/ui/ide/test/editors/stp/STPFormattingTest.java
new file mode 100644
index 0000000000..116db08670
--- /dev/null
+++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide.tests/src/org/eclipse/linuxtools/systemtap/ui/ide/test/editors/stp/STPFormattingTest.java
@@ -0,0 +1,424 @@
+/*******************************************************************************
+ * Copyright (c) 2013 Red Hat, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Red Hat - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.systemtap.ui.ide.test.editors.stp;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assume.assumeTrue;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.Document;
+import org.eclipse.jface.text.DocumentCommand;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IDocumentExtension3;
+import org.eclipse.jface.text.IDocumentPartitioner;
+import org.eclipse.linuxtools.internal.systemtap.ui.ide.editors.stp.STPAutoEditStrategy;
+import org.eclipse.linuxtools.internal.systemtap.ui.ide.editors.stp.STPPartitionScanner;
+import org.eclipse.linuxtools.internal.systemtap.ui.ide.editors.stp.STPPartitioner;
+import org.eclipse.linuxtools.systemtap.ui.ide.test.editors.stp.AbstractAutoEditTest.AutoEditTester;
+import org.eclipse.linuxtools.systemtap.ui.tests.SystemtapTest;
+import org.junit.Test;
+
+public class STPFormattingTest extends SystemtapTest{
+ protected IFile testFile;
+ protected Document testDocument;
+
+ /**
+ * A DocumentCommand with public constructor and exec method.
+ */
+ protected static class TestDocumentCommand extends DocumentCommand {
+
+ public TestDocumentCommand(int offset, int length, String text) {
+ super();
+ doit = true;
+ this.text = text;
+
+ this.offset = offset;
+ this.length = length;
+
+ owner = null;
+ caretOffset = -1;
+ }
+
+ /**
+ * @param doc
+ * @return the new caret position.
+ * @throws BadLocationException
+ */
+ public int exec(IDocument doc) throws BadLocationException {
+ doc.replace(offset, length, text);
+ return caretOffset != -1 ?
+ caretOffset :
+ offset + (text == null ? 0 : text.length());
+ }
+ }
+
+ /**
+ * Sets up the document partitioner for the given document for the given partitioning.
+ *
+ * @param document
+ * @param partitioning
+ * @param owner may be null
+ */
+ private void setupDocumentPartitioner(IDocument document, String partitioning) {
+ IDocumentPartitioner partitioner = new STPPartitioner(new STPPartitionScanner(), STPPartitionScanner.STP_PARTITION_TYPES);
+ if (document instanceof IDocumentExtension3) {
+ IDocumentExtension3 extension3= (IDocumentExtension3) document;
+ extension3.setDocumentPartitioner(partitioning, partitioner);
+ } else {
+ document.setDocumentPartitioner(partitioner);
+ }
+ partitioner.connect(document);
+ }
+
+ private AutoEditTester createAutoEditTester() {
+ IDocument doc = new Document();
+ setupDocumentPartitioner(doc, STPPartitionScanner.STP_PARTITIONING);
+ AutoEditTester tester = new AutoEditTester(doc, STPPartitionScanner.STP_PARTITIONING);
+
+ STPAutoEditStrategy s = new STPAutoEditStrategy(STPPartitionScanner.STP_PARTITIONING, null);
+ tester.setAutoEditStrategy(IDocument.DEFAULT_CONTENT_TYPE, s);
+ tester.setAutoEditStrategy(STPPartitionScanner.STP_COMMENT, s);
+ tester.setAutoEditStrategy(STPPartitionScanner.STP_CONDITIONAL, s);
+ return tester;
+ }
+
+ @Test
+ public void testEndProbeCompletion() throws BadLocationException {
+ assumeTrue(stapInstalled);
+ AutoEditTester tester = createAutoEditTester();
+
+ tester.type("probe end {\n");
+
+ // We are located on 2nd line
+ assertEquals(1, tester.getCaretLine());
+ // Nested location is indented
+ assertEquals(1, tester.getCaretColumn());
+ // The brace was closed automatically. Note, getLine() gets
+ // line from current position which is on line 1 of doc.
+ assertEquals("}", tester.getLine(1)); //$NON-NLS-1$
+ }
+
+ @Test
+ public void testSquareBracketCompletion() throws BadLocationException {
+ assumeTrue(stapInstalled);
+ AutoEditTester tester = createAutoEditTester();
+
+ tester.type("probe end {\n");
+
+ // We are located on 2nd line
+ assertEquals(1, tester.getCaretLine());
+
+ tester.type("a[");
+
+ // Verify automatic completion of square brackets
+ assertEquals(1, tester.getCaretLine());
+ assertEquals(3, tester.getCaretColumn());
+ assertEquals("\ta[]", tester.getLine());
+
+ tester.type("2]");
+
+ // Verify we can overwrite the end square-bracket
+ assertEquals(1, tester.getCaretLine());
+ assertEquals(5, tester.getCaretColumn());
+ assertEquals("\ta[2]", tester.getLine());
+
+ // Verify we don't add square brackets inside a string
+ tester.type("=\"b[");
+ assertEquals(1, tester.getCaretLine());
+ assertEquals(9, tester.getCaretColumn());
+ assertEquals("\ta[2]=\"b[\"", tester.getLine());
+
+ // Verify we don't add square brackets inside a comment
+ tester.goTo(tester.getCaretLine(), tester.getCaretColumn() + 1);
+ tester.type(" /* a[2");
+ assertEquals(1, tester.getCaretLine());
+ assertEquals(17, tester.getCaretColumn());
+ assertEquals("\ta[2]=\"b[\" /* a[2", tester.getLine());
+
+ // Verify we don't add square brackets inside a line comment
+ tester.type(" */ // a[2");
+ assertEquals(1, tester.getCaretLine());
+ assertEquals(27, tester.getCaretColumn());
+ assertEquals("\ta[2]=\"b[\" /* a[2 */ // a[2", tester.getLine());
+
+ // Verify we don't add square brackets inside a line comment
+ tester.type("\n# a[2");
+
+ assertEquals(2, tester.getCaretLine());
+ assertEquals(5, tester.getCaretColumn());
+ assertEquals("# a[2", tester.getLine());
+
+ // Verify we don't add square brackets inside a char specifier
+ tester.type("\na[3]='[");
+
+ System.out.println(tester.fDoc.get());
+ assertEquals(3, tester.getCaretLine());
+ assertEquals(8, tester.getCaretColumn());
+ assertEquals("\ta[3]='[", tester.getLine());
+
+ }
+
+ @Test
+ public void testBracketCompletion() throws BadLocationException {
+ assumeTrue(stapInstalled);
+ AutoEditTester tester = createAutoEditTester();
+
+ tester.type("probe end {\n");
+
+ // We are located on 2nd line
+ assertEquals(1, tester.getCaretLine());
+
+ // Verify we don't complete brackets inside a comment
+ tester.type("// if (a == b) {\n");
+
+ assertEquals(2, tester.getCaretLine());
+ assertEquals(1, tester.getCaretColumn());
+ assertEquals("\t", tester.getLine());
+
+ // verify we don't complete brackets inside a comment
+ tester.type("# if (a == b) {\n");
+
+ // Verify we can overwrite the end square-bracket
+ assertEquals(3, tester.getCaretLine());
+ assertEquals(1, tester.getCaretColumn());
+ assertEquals("\t", tester.getLine());
+
+ }
+
+ @Test
+ public void testQuoteCompletion() throws BadLocationException {
+ assumeTrue(stapInstalled);
+ AutoEditTester tester = createAutoEditTester();
+
+ tester.type("probe end {\n");
+
+ // We are located on 2nd line
+ assertEquals(1, tester.getCaretLine());
+
+ tester.type("a[2]=\"");
+
+ // Verify automatic completion of quotes
+ assertEquals(1, tester.getCaretLine());
+ assertEquals(7, tester.getCaretColumn());
+ assertEquals("\ta[2]=\"\"", tester.getLine());
+
+ tester.type("\\\"\"");
+
+ // Verify we can overwrite the auto end-quote without appending
+ // and escaped quotes can be added inside strings
+ assertEquals(1, tester.getCaretLine());
+ assertEquals(10, tester.getCaretColumn());
+ assertEquals("\ta[2]=\"\\\"\"", tester.getLine());
+
+ // Verify we don't add quotes inside a comment
+ tester.type(" /* \"");
+ assertEquals(1, tester.getCaretLine());
+ assertEquals(15, tester.getCaretColumn());
+ assertEquals("\ta[2]=\"\\\"\" /* \"", tester.getLine());
+
+ // Verify we don't add quotes inside a line comment
+ tester.type(" */ // \"");
+ assertEquals(1, tester.getCaretLine());
+ assertEquals(23, tester.getCaretColumn());
+ assertEquals("\ta[2]=\"\\\"\" /* \" */ // \"", tester.getLine());
+
+ // Verify we don't add quotes inside a line comment
+ tester.type("\n# \"");
+
+ assertEquals(2, tester.getCaretLine());
+ assertEquals(3, tester.getCaretColumn());
+ assertEquals("# \"", tester.getLine());
+
+ // Verify we don't add quotes inside a char specifier
+ tester.type("\na[3]='\"");
+
+ System.out.println(tester.fDoc.get());
+ assertEquals(3, tester.getCaretLine());
+ assertEquals(8, tester.getCaretColumn());
+ assertEquals("\ta[3]='\"", tester.getLine());
+
+ }
+
+ @Test
+ public void testIfCompletion() throws BadLocationException {
+ assumeTrue(stapInstalled);
+ AutoEditTester tester = createAutoEditTester();
+
+ tester.type("probe end {\n");
+
+ // We are located on 2nd line
+ assertEquals(1, tester.getCaretLine());
+ // Nested location is indented
+ assertEquals(1, tester.getCaretColumn());
+ // The brace was closed automatically. Note, getLine() gets
+ // line from current position which is on line 1 of doc.
+ assertEquals("}", tester.getLine(1)); //$NON-NLS-1$
+
+ tester.type("if (");
+
+ assertEquals(1, tester.getCaretLine());
+ assertEquals(5, tester.getCaretColumn());
+ assertEquals("\tif ()", tester.getLine());
+
+ // Verify we can overwrite the closing bracket for if
+ tester.type("a == b)");
+
+ assertEquals(1, tester.getCaretLine());
+ assertEquals(12, tester.getCaretColumn());
+ assertEquals("\tif (a == b)", tester.getLine());
+ }
+
+ @Test
+ public void testElseBracketCompletion() throws BadLocationException {
+ assumeTrue(stapInstalled);
+ AutoEditTester tester = createAutoEditTester();
+
+ tester.type("probe end {\n");
+
+ // We are located on 2nd line
+ assertEquals(1, tester.getCaretLine());
+ // Nested location is indented
+ assertEquals(1, tester.getCaretColumn());
+ // The brace was closed automatically. Note, getLine() gets
+ // line from current position which is on line 1 of doc.
+ assertEquals("}", tester.getLine(1)); //$NON-NLS-1$
+
+ tester.type("if (a == 2) {\n");
+
+ assertEquals(2, tester.getCaretLine());
+ assertEquals(2, tester.getCaretColumn());
+ assertEquals("\tif (a == 2) {", tester.getLine(-1));
+ assertEquals("\t}", tester.getLine(1));
+
+ tester.goTo(3, 2);
+
+ tester.type(" else {\n");
+
+ assertEquals(4, tester.getCaretLine());
+ assertEquals(2, tester.getCaretColumn());
+ assertEquals("\t}", tester.getLine(1));
+ }
+
+ @Test
+ public void testForCompletion() throws BadLocationException {
+ assumeTrue(stapInstalled);
+ AutoEditTester tester = createAutoEditTester();
+
+ tester.type("probe end {\n");
+
+ // We are located on 2nd line
+ assertEquals(1, tester.getCaretLine());
+ // Nested location is indented
+ assertEquals(1, tester.getCaretColumn());
+ // The brace was closed automatically. Note, getLine() gets
+ // line from current position which is on line 1 of doc.
+ assertEquals("}", tester.getLine(1)); //$NON-NLS-1$
+
+ tester.type("for (");
+
+ assertEquals(1, tester.getCaretLine());
+ assertEquals(6, tester.getCaretColumn());
+ assertEquals("\tfor ()", tester.getLine());
+ }
+
+ @Test
+ public void testForBracketCompletion() throws BadLocationException {
+ assumeTrue(stapInstalled);
+ AutoEditTester tester = createAutoEditTester();
+
+ tester.type("probe end {\n");
+
+ // We are located on 2nd line
+ assertEquals(1, tester.getCaretLine());
+ // Nested location is indented
+ assertEquals(1, tester.getCaretColumn());
+ // The brace was closed automatically. Note, getLine() gets
+ // line from current position which is on line 1 of doc.
+ assertEquals("}", tester.getLine(1)); //$NON-NLS-1$
+
+ tester.type("for (i = 0; i < 3; ++i) {\n");
+
+ assertEquals(2, tester.getCaretLine());
+ assertEquals(2, tester.getCaretColumn());
+ assertEquals("\t}", tester.getLine(1));
+ assertEquals("}", tester.getLine(2));
+ }
+
+ @Test
+ public void testWhileCompletion() throws BadLocationException {
+ assumeTrue(stapInstalled);
+ AutoEditTester tester = createAutoEditTester();
+
+ tester.type("probe end {\n");
+
+ // We are located on 2nd line
+ assertEquals(1, tester.getCaretLine());
+ // Nested location is indented
+ assertEquals(1, tester.getCaretColumn());
+ // The brace was closed automatically. Note, getLine() gets
+ // line from current position which is on line 1 of doc.
+ assertEquals("}", tester.getLine(1)); //$NON-NLS-1$
+
+ tester.type("while (");
+
+ assertEquals(1, tester.getCaretLine());
+ assertEquals(8, tester.getCaretColumn());
+ assertEquals("\twhile ()", tester.getLine());
+ }
+
+ @Test
+ public void testWhileBracketCompletion() throws BadLocationException {
+ assumeTrue(stapInstalled);
+ AutoEditTester tester = createAutoEditTester();
+
+ tester.type("probe end {\n");
+
+ // We are located on 2nd line
+ assertEquals(1, tester.getCaretLine());
+ // Nested location is indented
+ assertEquals(1, tester.getCaretColumn());
+ // The brace was closed automatically. Note, getLine() gets
+ // line from current position which is on line 1 of doc.
+ assertEquals("}", tester.getLine(1)); //$NON-NLS-1$
+
+ tester.type("while (i == 0) {\n");
+
+ assertEquals(2, tester.getCaretLine());
+ assertEquals(2, tester.getCaretColumn());
+ assertEquals("\t}", tester.getLine(1));
+ assertEquals("}", tester.getLine(2));
+ }
+
+ @Test
+ public void testForeachBracketCompletion() throws BadLocationException {
+ assumeTrue(stapInstalled);
+ AutoEditTester tester = createAutoEditTester();
+
+ tester.type("probe end {\n");
+
+ // We are located on 2nd line
+ assertEquals(1, tester.getCaretLine());
+ // Nested location is indented
+ assertEquals(1, tester.getCaretColumn());
+ // The brace was closed automatically. Note, getLine() gets
+ // line from current position which is on line 1 of doc.
+ assertEquals("}", tester.getLine(1)); //$NON-NLS-1$
+
+ tester.type("foreach (n in k+) {\n");
+
+ assertEquals(2, tester.getCaretLine());
+ assertEquals(2, tester.getCaretColumn());
+ assertEquals("\t}", tester.getLine(1));
+ assertEquals("}", tester.getLine(2));
+ }
+}
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide.tests/src/org/eclipse/linuxtools/systemtap/ui/ide/test/editors/stp/STPToggleCommentTest.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide.tests/src/org/eclipse/linuxtools/systemtap/ui/ide/test/editors/stp/STPToggleCommentTest.java
index b7bcd1ebef..f4e240290f 100644
--- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide.tests/src/org/eclipse/linuxtools/systemtap/ui/ide/test/editors/stp/STPToggleCommentTest.java
+++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide.tests/src/org/eclipse/linuxtools/systemtap/ui/ide/test/editors/stp/STPToggleCommentTest.java
@@ -19,6 +19,7 @@ import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.ITextSelection;
import org.eclipse.jface.text.Region;
import org.eclipse.linuxtools.internal.systemtap.ui.ide.actions.ToggleCommentHandler;
+import org.eclipse.linuxtools.internal.systemtap.ui.ide.editors.stp.STPDocumentProvider;
import org.junit.BeforeClass;
import org.junit.Test;
@@ -51,6 +52,20 @@ public class STPToggleCommentTest {
document = new Document(stpScript);
}
+ private static class MockSTPDocumentProvider extends STPDocumentProvider{
+ private IDocument document;
+
+ MockSTPDocumentProvider(IDocument document){
+ this.document = document;
+ this.setupDocument(document);
+ }
+
+ @Override
+ protected IDocument createDocument(Object element) {
+ return document;
+ }
+ }
+
@Test
public void getFirstCompleteLineOfRegionTest() {
IRegion scriptRegion;
@@ -82,7 +97,8 @@ public class STPToggleCommentTest {
@Test
public void isBlockCommentedTest() {
- IDocument document = new Document(stpScript);
+ MockSTPDocumentProvider provider = new MockSTPDocumentProvider(new Document(stpScript));
+ IDocument document = provider.createDocument(null);
String curLine;
for (int i = 0; i < PARTITIONED_SCRIPT.length; i++) {
curLine = PARTITIONED_SCRIPT[i];
@@ -120,7 +136,8 @@ public class STPToggleCommentTest {
int offset = stpScript.indexOf(scriptLine, curPos);
ITextSelection selection = new MockTextSelection(offset, lineLength, i, i, scriptLine);
- IDocument document = new Document(stpScript);
+ MockSTPDocumentProvider provider = new MockSTPDocumentProvider(new Document(stpScript));
+ IDocument document = provider.createDocument(null);
// for the purposes of this test, commented blocks start with "//"
assertEquals(scriptLine.startsWith("//"), cmdHandler.isSelectionCommented(selection, document));
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/IDEPlugin.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/IDEPlugin.java
index 538c07f7ce..d9e856013b 100644
--- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/IDEPlugin.java
+++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/IDEPlugin.java
@@ -11,15 +11,22 @@
package org.eclipse.linuxtools.internal.systemtap.ui.ide;
+import java.lang.reflect.InvocationTargetException;
import java.net.URI;
import java.net.URISyntaxException;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jface.dialogs.ErrorDialog;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.linuxtools.internal.systemtap.ui.ide.structures.TapsetLibrary;
import org.eclipse.linuxtools.systemtap.ui.consolelog.internal.ConsoleLogPlugin;
import org.eclipse.linuxtools.systemtap.ui.consolelog.preferences.ConsoleLogPreferenceConstants;
import org.eclipse.linuxtools.systemtap.ui.consolelog.structures.ScriptConsole;
+import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.IWorkbenchListener;
import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.osgi.framework.BundleContext;
@@ -34,6 +41,10 @@ public class IDEPlugin extends AbstractUIPlugin {
private IWorkbenchListener workbenchListener;
private static IDEPlugin plugin;
public static final String PLUGIN_ID = "org.eclipse.linuxtools.systemtap.ui.ide"; //$NON-NLS-1$
+ public static final String SPACE = "space"; //$NON-NLS-1$
+ public static final String INSERT = "insert"; //$NON-NLS-1$
+ public static final String DO_NOT_INSERT = "do not insert"; //$NON-NLS-1$
+ public static final String TAB = "tab"; //$NON-NLS-1$
public IDEPlugin() {
plugin = this;
@@ -99,4 +110,56 @@ public class IDEPlugin extends AbstractUIPlugin {
return null;
}
}
+
+ public static void log(IStatus status) {
+ ResourcesPlugin.getPlugin().getLog().log(status);
+ }
+
+ public static void logErrorMessage(String message) {
+ log(new Status(IStatus.ERROR, PLUGIN_ID, IStatus.ERROR, message, null));
+ }
+
+ public static void logException(Throwable e, final String title, String message) {
+ if (e instanceof InvocationTargetException) {
+ e = ((InvocationTargetException) e).getTargetException();
+ }
+ IStatus status = null;
+ if (e instanceof CoreException)
+ status = ((CoreException) e).getStatus();
+ else {
+ if (message == null)
+ message = e.getMessage();
+ if (message == null)
+ message = e.toString();
+ status = new Status(IStatus.ERROR, PLUGIN_ID, IStatus.OK, message, e);
+ }
+ ResourcesPlugin.getPlugin().getLog().log(status);
+ Display display;
+ display = Display.getCurrent();
+ if (display == null)
+ display = Display.getDefault();
+ final IStatus fstatus = status;
+ display.asyncExec(new Runnable() {
+ @Override
+ public void run() {
+ ErrorDialog.openError(null, title, null, fstatus);
+ }
+ });
+ }
+
+ public static void logException(Throwable e) {
+ logException(e, null, null);
+ }
+
+ public static void log(Throwable e) {
+ if (e instanceof InvocationTargetException)
+ e = ((InvocationTargetException) e).getTargetException();
+ IStatus status = null;
+ if (e instanceof CoreException)
+ status = ((CoreException) e).getStatus();
+ else
+ status = new Status(IStatus.ERROR, PLUGIN_ID, IStatus.OK, e.getMessage(), e);
+ log(status);
+ }
+
}
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/actions/ToggleCommentHandler.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/actions/ToggleCommentHandler.java
index 395a5b4f6b..5370dc1ac5 100644
--- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/actions/ToggleCommentHandler.java
+++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/actions/ToggleCommentHandler.java
@@ -15,7 +15,6 @@ import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
-import org.eclipse.jface.text.IDocumentExtension3;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.ITextOperationTarget;
import org.eclipse.jface.text.ITextSelection;
@@ -25,6 +24,7 @@ import org.eclipse.jface.text.TextUtilities;
import org.eclipse.jface.text.TextViewer;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.linuxtools.internal.systemtap.ui.ide.Localization;
+import org.eclipse.linuxtools.internal.systemtap.ui.ide.editors.stp.STPPartitionScanner;
import org.eclipse.linuxtools.systemtap.graphingapi.ui.widgets.ExceptionErrorDialog;
import org.eclipse.swt.custom.BusyIndicator;
import org.eclipse.swt.widgets.Display;
@@ -140,7 +140,7 @@ public class ToggleCommentHandler extends AbstractHandler {
try {
IRegion block = getTextBlockFromSelection(textSelection, document);
ITypedRegion[] regions = TextUtilities.computePartitioning(
- document, IDocumentExtension3.DEFAULT_PARTITIONING,
+ document, STPPartitionScanner.STP_PARTITIONING,
block.getOffset(), block.getLength(), false);
int[] lines = new int[regions.length * 2]; // [startline, endline,
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/AbortFormatting.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/AbortFormatting.java
new file mode 100644
index 0000000000..b11ffcffba
--- /dev/null
+++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/AbortFormatting.java
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2007, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ * Anton Leherbauer (Wind River Systems)
+ * Red Hat Inc. - modified for use in SystemTap
+ *******************************************************************************/
+package org.eclipse.linuxtools.internal.systemtap.ui.ide.editors.stp;
+
+/**
+ * Unchecked exception wrapping invalid input checked exception which may occur
+ * when scanning original formatted source.
+ *
+ * @since 4.0
+ */
+public class AbortFormatting extends RuntimeException {
+
+ private static final long serialVersionUID= -5796507276311428526L;
+ Throwable nestedException;
+
+ public AbortFormatting(String message) {
+ super(message);
+ }
+ public AbortFormatting(Throwable cause) {
+ super(cause);
+ }
+}
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/AlignmentException.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/AlignmentException.java
new file mode 100644
index 0000000000..0e3f39a11c
--- /dev/null
+++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/AlignmentException.java
@@ -0,0 +1,53 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ * Red Hat Inc. - copied into SystemTap
+ *******************************************************************************/
+package org.eclipse.linuxtools.internal.systemtap.ui.ide.editors.stp;
+
+/**
+ * Exception used to backtrack and break available alignments
+ * When the exception is thrown, it is assumed that some alignment will be changed.
+ *
+ * @since 4.0
+ */
+public class AlignmentException extends RuntimeException {
+ private static final long serialVersionUID= -1081237230006524966L;
+ public static final int LINE_TOO_LONG = 1;
+ public static final int ALIGN_TOO_SMALL = 2;
+
+ int reason;
+ int value;
+ public int relativeDepth;
+
+ public AlignmentException(int reason, int relativeDepth) {
+ this(reason, 0, relativeDepth);
+ }
+
+ public AlignmentException(int reason, int value, int relativeDepth) {
+ this.reason = reason;
+ this.value = value;
+ this.relativeDepth = relativeDepth;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder buffer = new StringBuilder(40);
+ switch (reason) {
+ case LINE_TOO_LONG:
+ buffer.append("LINE_TOO_LONG"); //$NON-NLS-1$
+ break;
+ case ALIGN_TOO_SMALL:
+ buffer.append("ALIGN_TOO_SMALL"); //$NON-NLS-1$
+ break;
+ }
+ buffer.append("<relativeDepth: ").append(relativeDepth).append(">\n"); //$NON-NLS-1$ //$NON-NLS-2$
+ return buffer.toString();
+ }
+}
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/CharArrayUtils.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/CharArrayUtils.java
new file mode 100644
index 0000000000..8181eb32de
--- /dev/null
+++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/CharArrayUtils.java
@@ -0,0 +1,374 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2009, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ * Andrew Ferguson (Symbian)
+ * Markus Schorn (Wind River Systems)
+ * Sergey Prigogin (Google)
+ * Red Hat Inc. - modified for use in SystemTap
+ *******************************************************************************/
+package org.eclipse.linuxtools.internal.systemtap.ui.ide.editors.stp;
+
+import java.util.Arrays;
+
+/**
+ * A static utility class for char arrays
+ * @author dschaefe
+ */
+public class CharArrayUtils {
+ /** @since 5.4 */
+ public static final char[] EMPTY_CHAR_ARRAY = {};
+ public static final char[] EMPTY = EMPTY_CHAR_ARRAY;
+
+ private CharArrayUtils() {}
+
+ public static final int hash(char[] str, int start, int length) {
+ int h = 0;
+ int end = start + length;
+
+ for (int curr = start; curr < end; ++curr) {
+ h += (h << 3) + str[curr];
+ }
+
+ return h;
+ }
+
+ public static final int hash(char[] str) {
+ return hash(str, 0, str.length);
+ }
+
+ public static final boolean equals(char[] str1, char[] str2) {
+ return Arrays.equals(str1, str2);
+ }
+
+ public static final boolean equals(char[][] strarr1, char[][] strarr2) {
+ if (strarr1.length != strarr2.length) {
+ return false;
+ }
+ for (int i = 0; i < strarr2.length; i++) {
+ if (!Arrays.equals(strarr1[i], strarr2[i])) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Returns {@code true} if the contents of a character array are the same as contents
+ * of a string.
+ * @since 5.4
+ */
+ public static final boolean equals(char[] str1, String str2) {
+ int length = str1.length;
+ if (str2.length() != length)
+ return false;
+
+ for (int i = 0; i < length; i++) {
+ if (str1[i] != str2.charAt(i))
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Returns {@code true} if the contents of a section of a character array are the same as
+ * contents of a string.
+ * @since 5.5
+ */
+ public static final boolean equals(char[] str1, int start1, int length1, String str2) {
+ if (length1 != str2.length() || str1.length < length1 + start1)
+ return false;
+ for (int i = 0; i < length1; ++i) {
+ if (str1[start1++] != str2.charAt(i))
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Returns {@code true} if a prefix of the character array is the same as contents
+ * of a string.
+ * @since 5.4
+ */
+ public static final boolean startsWith(char[] str1, String str2) {
+ int len = str2.length();
+ if (str1.length < len)
+ return false;
+ for (int i = 0; i < len; i++) {
+ if (str1[i] != str2.charAt(i)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Implements a lexicographical comparator for char arrays. Comparison is done
+ * on a per char basis, not a code-point basis.
+ *
+ * @param str1 the first of the two char arrays to compare
+ * @param str2 the second of the two char arrays to compare
+ * @return 0 if str1==str2, -1 if str1 &lt; str2 and 1 if str1 &gt; str2
+ */
+ /*
+ * aftodo - we should think about using the Character codepoint static methods
+ * if we move to Java 5
+ */
+ public static final int compare(char[] str1, char[] str2) {
+ if (str1 == str2)
+ return 0;
+
+ int end= Math.min(str1.length, str2.length);
+ for (int i = 0; i < end; ++i) {
+ int diff= str1[i] - str2[i];
+ if (diff != 0)
+ return diff;
+ }
+
+ return str1.length - str2.length;
+ }
+
+ /**
+ * Returns {@code true} if the contents of a section of a character array are the same as
+ * contents of another character array.
+ */
+ public static final boolean equals(char[] str1, int start1, int length1, char[] str2) {
+ if (length1 != str2.length || str1.length < length1 + start1)
+ return false;
+ if (str1 == str2 && start1 == 0)
+ return true;
+ for (int i = 0; i < length1; ++i) {
+ if (str1[start1++] != str2[i])
+ return false;
+ }
+
+ return true;
+ }
+
+ public static final boolean equals(char[] str1, int start1, int length1, char[] str2, boolean ignoreCase) {
+ if (!ignoreCase)
+ return equals(str1, start1, length1, str2);
+
+ if (length1 != str2.length || str1.length < start1 + length1)
+ return false;
+
+ for (int i = 0; i < length1; ++i) {
+ if (Character.toLowerCase(str1[start1++]) != Character.toLowerCase(str2[i]))
+ return false;
+ }
+ return true;
+ }
+
+ public static final char[] extract(char[] str, int start, int length) {
+ if (start == 0 && length == str.length)
+ return str;
+
+ char[] copy = new char[length];
+ System.arraycopy(str, start, copy, 0, length);
+ return copy;
+ }
+
+ public static final char[] concat(char[] first, char[] second) {
+ if (first == null)
+ return second;
+ if (second == null)
+ return first;
+
+ int length1 = first.length;
+ int length2 = second.length;
+ char[] result = new char[length1 + length2];
+ System.arraycopy(first, 0, result, 0, length1);
+ System.arraycopy(second, 0, result, length1, length2);
+ return result;
+ }
+
+ public static final char[] replace(char[] array, char[] toBeReplaced, char[] replacementChars) {
+ int max = array.length;
+ int replacedLength = toBeReplaced.length;
+ int replacementLength = replacementChars.length;
+
+ int[] starts = new int[5];
+ int occurrenceCount = 0;
+
+ if (!equals(toBeReplaced, replacementChars)) {
+ next: for (int i = 0; i < max; i++) {
+ int j = 0;
+ while (j < replacedLength) {
+ if (i + j == max)
+ continue next;
+ if (array[i + j] != toBeReplaced[j++])
+ continue next;
+ }
+ if (occurrenceCount == starts.length) {
+ System.arraycopy(starts, 0, starts = new int[occurrenceCount * 2], 0,
+ occurrenceCount);
+ }
+ starts[occurrenceCount++] = i;
+ }
+ }
+ if (occurrenceCount == 0)
+ return array;
+ char[] result = new char[max + occurrenceCount * (replacementLength - replacedLength)];
+ int inStart = 0, outStart = 0;
+ for (int i = 0; i < occurrenceCount; i++) {
+ int offset = starts[i] - inStart;
+ System.arraycopy(array, inStart, result, outStart, offset);
+ inStart += offset;
+ outStart += offset;
+ System.arraycopy(
+ replacementChars,
+ 0,
+ result,
+ outStart,
+ replacementLength);
+ inStart += replacedLength;
+ outStart += replacementLength;
+ }
+ System.arraycopy(array, inStart, result, outStart, max - inStart);
+ return result;
+ }
+
+ public static final char[][] subarray(char[][] array, int start, int end) {
+ if (end == -1)
+ end = array.length;
+ if (start > end)
+ return null;
+ if (start < 0)
+ return null;
+ if (end > array.length)
+ return null;
+
+ char[][] result = new char[end - start][];
+ System.arraycopy(array, start, result, 0, end - start);
+ return result;
+ }
+
+ public static final char[] subarray(char[] array, int start, int end) {
+ if (end == -1)
+ end = array.length;
+ if (start > end)
+ return null;
+ if (start < 0)
+ return null;
+ if (end > array.length)
+ return null;
+
+ char[] result = new char[end - start];
+ System.arraycopy(array, start, result, 0, end - start);
+ return result;
+ }
+
+ public static final int indexOf(char toBeFound, char[] array) {
+ for (int i = 0; i < array.length; i++) {
+ if (toBeFound == array[i])
+ return i;
+ }
+ return -1;
+ }
+
+ public static int indexOf(char toBeFound, char[] buffer, int start, int end) {
+ if (start < 0 || start > buffer.length || end > buffer.length)
+ return -1;
+
+ for (int i = start; i < end; i++) {
+ if (toBeFound == buffer[i])
+ return i;
+ }
+ return -1;
+ }
+
+ public static final int indexOf(char[] toBeFound, char[] array) {
+ if (toBeFound.length > array.length)
+ return -1;
+
+ int j = 0;
+ for (int i = 0; i < array.length; i++) {
+ if (toBeFound[j] == array[i]) {
+ if (++j == toBeFound.length)
+ return i - j + 1;
+ } else {
+ j = 0;
+ }
+ }
+ return -1;
+ }
+
+ public static final int lastIndexOf(char[] toBeFound, char[] array) {
+ int j = toBeFound.length - 1;
+ for (int i = array.length; --i >= 0;) {
+ if (toBeFound[j] == array[i]) {
+ if (--j == -1)
+ return i;
+ } else {
+ j = toBeFound.length - 1;
+ }
+ }
+ return -1;
+ }
+
+ static final public char[] trim(char[] chars) {
+ if (chars == null)
+ return null;
+
+ int start = 0, length = chars.length, end = length - 1;
+ while (start < length && chars[start] == ' ') {
+ start++;
+ }
+ while (end > start && chars[end] == ' ') {
+ end--;
+ }
+ if (start != 0 || end != length - 1) {
+ return subarray(chars, start, end + 1);
+ }
+ return chars;
+ }
+
+ static final public char[] lastSegment(char[] array, char[] separator) {
+ int pos = lastIndexOf(separator, array);
+ if (pos < 0)
+ return array;
+ return subarray(array, pos + separator.length, array.length);
+ }
+
+ /**
+ * @param buff
+ * @param i
+ * @param charImage
+ */
+ public static void overWrite(char[] buff, int i, char[] charImage) {
+ if (buff.length < i + charImage.length)
+ return;
+ for (int j = 0; j < charImage.length; j++) {
+ buff[i + j] = charImage[j];
+ }
+ }
+
+ /**
+ * Finds an array of chars in an array of arrays of chars.
+ * @return offset where the array was found or <code>-1</code>
+ */
+ public static int indexOf(final char[] searchFor, final char[][] searchIn) {
+ for (int i = 0; i < searchIn.length; i++) {
+ if (equals(searchIn[i], searchFor)) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ /**
+ * Converts a {@link StringBuilder} to a character array.
+ * @since 5.5
+ */
+ public static char[] extractChars(StringBuilder buf) {
+ final int len = buf.length();
+ char[] result= new char[len];
+ buf.getChars(0, len, result, 0);
+ return result;
+ }
+}
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/CodeFormatterUtil.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/CodeFormatterUtil.java
new file mode 100644
index 0000000000..6d769b7e71
--- /dev/null
+++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/CodeFormatterUtil.java
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * Copyright (c) 2013 Red Hat, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Red Hat - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.linuxtools.internal.systemtap.ui.ide.editors.stp;
+
+import org.eclipse.core.resources.IProject;
+
+public class CodeFormatterUtil {
+
+ public static int getTabWidth(IProject fProject) {
+ // TODO Auto-generated method stub
+ return 4;
+ }
+
+ public static int getIndentWidth(IProject fProject) {
+ // TODO Auto-generated method stub
+ return 4;
+ }
+
+}
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/DocumentCharacterIterator.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/DocumentCharacterIterator.java
new file mode 100644
index 0000000000..f73ce5ac0c
--- /dev/null
+++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/DocumentCharacterIterator.java
@@ -0,0 +1,246 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2011, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ * Red Hat Inc. - modified for use in SystemTap
+ *******************************************************************************/
+package org.eclipse.linuxtools.internal.systemtap.ui.ide.editors.stp;
+
+import java.text.CharacterIterator;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+
+
+/**
+ * An <code>IDocument</code> based implementation of
+ * <code>CharacterIterator</code> and <code>CharSequence</code>. Note that
+ * the supplied document is not copied; if the document is modified during the
+ * lifetime of a <code>DocumentCharacterIterator</code>, the methods
+ * returning document content may not always return the same values. Also, if
+ * accessing the document fails with a {@link BadLocationException}, any of
+ * <code>CharacterIterator</code> methods as well as <code>charAt</code>may
+ * return {@link CharacterIterator#DONE}.
+ *
+ * @since 4.0
+ */
+public class DocumentCharacterIterator implements CharacterIterator, CharSequence {
+
+ private int fIndex= -1;
+ private final IDocument fDocument;
+ private final int fFirst;
+ private final int fLast;
+
+ private void invariant() {
+ Assert.isTrue(fIndex >= fFirst);
+ Assert.isTrue(fIndex <= fLast);
+ }
+
+ /**
+ * Creates an iterator for the entire document.
+ *
+ * @param document the document backing this iterator
+ */
+ public DocumentCharacterIterator(IDocument document) {
+ this(document, 0);
+ }
+
+ /**
+ * Creates an iterator, starting at offset <code>first</code>.
+ *
+ * @param document the document backing this iterator
+ * @param first the first character to consider
+ * @throws IllegalArgumentException if the indices are out of bounds
+ */
+ public DocumentCharacterIterator(IDocument document, int first) throws IllegalArgumentException {
+ this(document, first, document.getLength());
+ }
+
+ /**
+ * Creates an iterator for the document contents from <code>first</code>
+ * (inclusive) to <code>last</code> (exclusive).
+ *
+ * @param document the document backing this iterator
+ * @param first the first character to consider
+ * @param last the last character index to consider
+ * @throws IllegalArgumentException if the indices are out of bounds
+ */
+ public DocumentCharacterIterator(IDocument document, int first, int last) throws IllegalArgumentException {
+ if (document == null)
+ throw new NullPointerException();
+ if (first < 0 || first > last)
+ throw new IllegalArgumentException();
+ if (last > document.getLength())
+ throw new IllegalArgumentException();
+ fDocument= document;
+ fFirst= first;
+ fLast= last;
+ fIndex= first;
+ invariant();
+ }
+
+ /*
+ * @see java.text.CharacterIterator#first()
+ */
+ @Override
+ public char first() {
+ return setIndex(getBeginIndex());
+ }
+
+ /*
+ * @see java.text.CharacterIterator#last()
+ */
+ @Override
+ public char last() {
+ if (fFirst == fLast)
+ return setIndex(getEndIndex());
+ return setIndex(getEndIndex() - 1);
+ }
+
+ /*
+ * @see java.text.CharacterIterator#current()
+ */
+ @Override
+ public char current() {
+ if (fIndex >= fFirst && fIndex < fLast)
+ try {
+ return fDocument.getChar(fIndex);
+ } catch (BadLocationException e) {
+ // ignore
+ }
+ return DONE;
+ }
+
+ /*
+ * @see java.text.CharacterIterator#next()
+ */
+ @Override
+ public char next() {
+ return setIndex(Math.min(fIndex + 1, getEndIndex()));
+ }
+
+ /*
+ * @see java.text.CharacterIterator#previous()
+ */
+ @Override
+ public char previous() {
+ if (fIndex > getBeginIndex()) {
+ return setIndex(fIndex - 1);
+ }
+ return DONE;
+ }
+
+ /*
+ * @see java.text.CharacterIterator#setIndex(int)
+ */
+ @Override
+ public char setIndex(int position) {
+ if (position >= getBeginIndex() && position <= getEndIndex())
+ fIndex= position;
+ else
+ throw new IllegalArgumentException();
+
+ invariant();
+ return current();
+ }
+
+ /*
+ * @see java.text.CharacterIterator#getBeginIndex()
+ */
+ @Override
+ public int getBeginIndex() {
+ return fFirst;
+ }
+
+ /*
+ * @see java.text.CharacterIterator#getEndIndex()
+ */
+ @Override
+ public int getEndIndex() {
+ return fLast;
+ }
+
+ /*
+ * @see java.text.CharacterIterator#getIndex()
+ */
+ @Override
+ public int getIndex() {
+ return fIndex;
+ }
+
+ /*
+ * @see java.text.CharacterIterator#clone()
+ */
+ @Override
+ public Object clone() {
+ try {
+ return super.clone();
+ } catch (CloneNotSupportedException e) {
+ throw new InternalError();
+ }
+ }
+
+ /*
+ * @see java.lang.CharSequence#length()
+ */
+ @Override
+ public int length() {
+ return getEndIndex() - getBeginIndex();
+ }
+
+ /**
+ * {@inheritDoc}
+ * <p>
+ * Note that, if the document is modified concurrently, this method may
+ * return {@link CharacterIterator#DONE} if a {@link BadLocationException}
+ * was thrown when accessing the backing document.
+ * </p>
+ *
+ * @param index {@inheritDoc}
+ * @return {@inheritDoc}
+ */
+ @Override
+ public char charAt(int index) {
+ if (index >= 0 && index < length())
+ try {
+ return fDocument.getChar(getBeginIndex() + index);
+ } catch (BadLocationException e) {
+ // ignore and return DONE
+ return DONE;
+ }
+ throw new IndexOutOfBoundsException();
+ }
+
+ /*
+ * @see java.lang.CharSequence#subSequence(int, int)
+ */
+ @Override
+ public CharSequence subSequence(int start, int end) {
+ if (start < 0)
+ throw new IndexOutOfBoundsException();
+ if (end < start)
+ throw new IndexOutOfBoundsException();
+ if (end > length())
+ throw new IndexOutOfBoundsException();
+ return new DocumentCharacterIterator(fDocument, getBeginIndex() + start, getBeginIndex() + end);
+ }
+
+ /*
+ * @see java.lang.CharSequence#toString()
+ */
+ @Override
+ public String toString() {
+ int length = length();
+ char[] chs = new char[length];
+ for (int i=0; i<length; ++i) {
+ chs[i] = charAt(i);
+ }
+ return new String(chs);
+ }
+}
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/IndentUtil.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/IndentUtil.java
new file mode 100644
index 0000000000..6631619f29
--- /dev/null
+++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/IndentUtil.java
@@ -0,0 +1,655 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2010, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ * Sergey Prigogin, Google
+ * Anton Leherbauer (Wind River Systems)
+ * Red Hat Inc. - modified for use in SystemTap
+ *******************************************************************************/
+package org.eclipse.linuxtools.internal.systemtap.ui.ide.editors.stp;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITypedRegion;
+import org.eclipse.jface.text.TextUtilities;
+import org.eclipse.jface.text.source.ILineRange;
+import org.eclipse.jface.text.source.LineRange;
+
+
+/**
+ * Utility that indents a number of lines in a document.
+ */
+public final class IndentUtil {
+
+ private static final String SLASHES= "//"; //$NON-NLS-1$
+
+ /**
+ * The result of an indentation operation. The result may be passed to
+ * subsequent calls to
+ * {@link IndentUtil#indentLines(IDocument, ILineRange, IProject, IndentUtil.IndentResult) indentLines}
+ * to obtain consistent results with respect to the indentation of
+ * line-comments.
+ */
+ public static final class IndentResult {
+ private IndentResult(boolean[] commentLines) {
+ commentLinesAtColumnZero= commentLines;
+ }
+ private boolean[] commentLinesAtColumnZero;
+ private boolean hasChanged;
+ private int leftmostLine= -1;
+ /**
+ * Returns <code>true</code> if the indentation operation changed the
+ * document, <code>false</code> if not.
+ * @return <code>true</code> if the document was changed
+ */
+ public boolean hasChanged() {
+ return hasChanged;
+ }
+ }
+
+ private IndentUtil() {
+ // do not instantiate
+ }
+
+ /**
+ * Indents the line range specified by <code>lines</code> in
+ * <code>document</code>. The passed C project may be
+ * <code>null</code>, it is used solely to obtain formatter preferences.
+ *
+ * @param document the document to be changed
+ * @param lines the line range to be indented
+ * @param project the C project to get the formatter preferences from, or
+ * <code>null</code> if global preferences should be used
+ * @param result the result from a previous call to <code>indentLines</code>,
+ * in order to maintain comment line properties, or <code>null</code>.
+ * Note that the passed result may be changed by the call.
+ * @return an indent result that may be queried for changes and can be
+ * reused in subsequent indentation operations
+ * @throws BadLocationException if <code>lines</code> is not a valid line
+ * range on <code>document</code>
+ */
+ public static IndentResult indentLines(IDocument document, ILineRange lines, IProject project, IndentResult result) throws BadLocationException {
+ int numberOfLines= lines.getNumberOfLines();
+
+ if (numberOfLines < 1)
+ return new IndentResult(null);
+
+ result= reuseOrCreateToken(result, numberOfLines);
+
+ STPHeuristicScanner scanner= new STPHeuristicScanner(document);
+ STPIndenter indenter= new STPIndenter(document, scanner, project);
+ boolean changed= false;
+ int tabSize= CodeFormatterUtil.getTabWidth(project);
+ boolean indentInsideLineComments= indentInsideLineComments(project);
+ for (int line= lines.getStartLine(), last= line + numberOfLines, i= 0; line < last; line++) {
+ changed |= indentLine(document, line, indenter, scanner, result.commentLinesAtColumnZero, i++, tabSize, indentInsideLineComments);
+ }
+ result.hasChanged= changed;
+
+ return result;
+ }
+
+ /**
+ * Inserts <code>indent</code> string at the beginning of each line in <code>lines</code>.
+ * @param document the document to be changed.
+ * @param lines the line range to be indented.
+ * @param indent the indent string to be inserted.
+ * @throws BadLocationException if <code>lines</code> is not a valid line
+ * range on <code>document</code>
+ */
+ public static void indentLines(IDocument document, LineRange lines, String indent) throws BadLocationException {
+ int numberOfLines= lines.getNumberOfLines();
+ for (int line= lines.getStartLine(), last= line + numberOfLines; line < last; line++) {
+ int offset= document.getLineOffset(line);
+ document.replace(offset, 0, indent);
+ }
+ }
+
+ /**
+ * Returns <code>true</code> if line comments at column 0 should be indented inside, <code>false</code> otherwise.
+ *
+ * @param project the project to get project specific options from
+ * @return <code>true</code> if line comments at column 0 should be indented inside, <code>false</code> otherwise.
+ */
+ public static boolean indentInsideLineComments(IProject project) {
+ return STPDefaultCodeFormatterConstants.TRUE.equals(getCoreOption(project, STPDefaultCodeFormatterConstants.FORMATTER_INDENT_INSIDE_LINE_COMMENTS));
+ }
+
+ /**
+ * Returns the possibly <code>project</code>-specific core preference
+ * defined under <code>key</code>.
+ *
+ * @param project the project to get the preference from, or
+ * <code>null</code> to get the global preference
+ * @param key the key of the preference
+ * @return the value of the preference
+ */
+ private static String getCoreOption(IProject project, String key) {
+// return project.getOption(key, true);
+ return "true"; //$NON-NLS-1$ // for now, just return true
+ }
+
+ /**
+ * Shifts the line range specified by <code>lines</code> in
+ * <code>document</code>. The amount that the lines get shifted
+ * are determined by the first line in the range, all subsequent
+ * lines are adjusted accordingly. The passed C project may be
+ * <code>null</code>, it is used solely to obtain formatter
+ * preferences.
+ *
+ * @param document the document to be changed
+ * @param lines the line range to be shifted
+ * @param project the C project to get the formatter preferences
+ * from, or <code>null</code> if global preferences should
+ * be used
+ * @param result the result from a previous call to
+ * <code>shiftLines</code>, in order to maintain comment
+ * line properties, or <code>null</code>. Note that the
+ * passed result may be changed by the call.
+ * @return an indent result that may be queried for changes and can
+ * be reused in subsequent indentation operations
+ * @throws BadLocationException if <code>lines</code> is not a
+ * valid line range on <code>document</code>
+ */
+ public static IndentResult shiftLines(IDocument document, ILineRange lines, IProject project, IndentResult result) throws BadLocationException {
+ int numberOfLines= lines.getNumberOfLines();
+
+ if (numberOfLines < 1)
+ return new IndentResult(null);
+
+ result= reuseOrCreateToken(result, numberOfLines);
+ result.hasChanged= false;
+
+ STPHeuristicScanner scanner= new STPHeuristicScanner(document);
+ STPIndenter indenter= new STPIndenter(document, scanner, project);
+
+ boolean indentInsideLineComments= indentInsideLineComments(project);
+ String current= getCurrentIndent(document, lines.getStartLine(), indentInsideLineComments);
+ StringBuilder correct= new StringBuilder(computeIndent(document, lines.getStartLine(), indenter, scanner));
+
+ int tabSize= CodeFormatterUtil.getTabWidth(project);
+ StringBuilder addition= new StringBuilder();
+ int difference= subtractIndent(correct, current, addition, tabSize);
+
+ if (difference == 0)
+ return result;
+
+ if (result.leftmostLine == -1)
+ result.leftmostLine= getLeftMostLine(document, lines, tabSize, indentInsideLineComments);
+
+ int maxReduction= computeVisualLength(getCurrentIndent(document, result.leftmostLine + lines.getStartLine(), indentInsideLineComments), tabSize);
+
+ if (difference > 0) {
+ for (int line= lines.getStartLine(), last= line + numberOfLines, i= 0; line < last; line++)
+ addIndent(document, line, addition, result.commentLinesAtColumnZero, i++, indentInsideLineComments);
+ } else {
+ int reduction= Math.min(-difference, maxReduction);
+ for (int line= lines.getStartLine(), last= line + numberOfLines, i= 0; line < last; line++)
+ cutIndent(document, line, reduction, tabSize, result.commentLinesAtColumnZero, i++, indentInsideLineComments);
+ }
+
+ result.hasChanged= true;
+
+ return result;
+
+ }
+
+ /**
+ * Indents line <code>line</code> in <code>document</code> with <code>indent</code>.
+ * Leaves leading comment signs alone.
+ *
+ * @param document the document
+ * @param line the line
+ * @param indent the indentation to insert
+ * @param commentlines
+ * @param relative
+ * @param indentInsideLineComments option whether to indent inside line comments starting at column 0
+ * @throws BadLocationException on concurrent document modification
+ */
+ private static void addIndent(IDocument document, int line, CharSequence indent, boolean[] commentlines, int relative, boolean indentInsideLineComments) throws BadLocationException {
+ IRegion region= document.getLineInformation(line);
+ int insert= region.getOffset();
+ int endOffset= region.getOffset() + region.getLength();
+
+ if (indentInsideLineComments) {
+ // go behind line comments
+ if (!commentlines[relative]) {
+ while (insert < endOffset - 2 && document.get(insert, 2).equals(SLASHES))
+ insert += 2;
+ }
+ }
+
+ // insert indent
+ document.replace(insert, 0, indent.toString());
+ }
+
+ /**
+ * Cuts the visual equivalent of <code>toDelete</code> characters out of the
+ * indentation of line <code>line</code> in <code>document</code>.
+ *
+ * @param document
+ * @param line
+ * @param shiftWidth
+ * @param tabWidth
+ * @return number of characters deleted
+ * @throws BadLocationException
+ */
+ public static int cutIndent(IDocument document, int line, int shiftWidth, int tabWidth) throws BadLocationException {
+ return cutIndent(document, line, shiftWidth, tabWidth, new boolean[1], 0, false);
+ }
+
+ /**
+ * Cuts the visual equivalent of <code>toDelete</code> characters out of the
+ * indentation of line <code>line</code> in <code>document</code>. Leaves
+ * leading comment signs alone if desired.
+ *
+ * @param document the document
+ * @param line the line
+ * @param toDelete the number of space equivalents to delete.
+ * @param commentLines
+ * @param relative
+ * @param indentInsideLineComments option whether to indent inside line comments starting at column 0
+ * @return number of characters deleted
+ * @throws BadLocationException on concurrent document modification
+ */
+ private static int cutIndent(IDocument document, int line, int toDelete, int tabSize, boolean[] commentLines, int relative, boolean indentInsideLineComments) throws BadLocationException {
+ IRegion region= document.getLineInformation(line);
+ int from= region.getOffset();
+ int endOffset= region.getOffset() + region.getLength();
+
+ if (indentInsideLineComments) {
+ // go behind line comments
+ while (from < endOffset - 2 && document.get(from, 2).equals(SLASHES))
+ from += 2;
+ }
+
+ int to= from;
+ while (toDelete > 0 && to < endOffset) {
+ char ch= document.getChar(to);
+ if (!Character.isWhitespace(ch))
+ break;
+ toDelete -= computeVisualLength(ch, tabSize);
+ if (toDelete >= 0)
+ to++;
+ else
+ break;
+ }
+
+ if (endOffset > to + 1 && document.get(to, 2).equals(SLASHES))
+ commentLines[relative]= true;
+
+ document.replace(from, to - from, ""); //$NON-NLS-1$
+ return to - from;
+ }
+
+ /**
+ * Computes the difference of two indentations and returns the difference in
+ * length of current and correct. If the return value is positive, <code>addition</code>
+ * is initialized with a substring of that length of <code>correct</code>.
+ *
+ * @param correct the correct indentation
+ * @param current the current indentation (migth contain non-whitespace)
+ * @param difference a string buffer - if the return value is positive, it will be cleared and set to the substring of <code>current</code> of that length
+ * @return the difference in lenght of <code>correct</code> and <code>current</code>
+ */
+ private static int subtractIndent(CharSequence correct, CharSequence current, StringBuilder difference, int tabSize) {
+ int c1= computeVisualLength(correct, tabSize);
+ int c2= computeVisualLength(current, tabSize);
+ int diff= c1 - c2;
+ if (diff <= 0)
+ return diff;
+
+ difference.setLength(0);
+ int len= 0, i= 0;
+ while (len < diff) {
+ char c= correct.charAt(i++);
+ difference.append(c);
+ len += computeVisualLength(c, tabSize);
+ }
+
+
+ return diff;
+ }
+
+ private static int computeVisualLength(char ch, int tabSize) {
+ if (ch == '\t')
+ return tabSize;
+ return 1;
+ }
+
+ /**
+ * Returns the visual length of a given <code>CharSequence</code> taking into
+ * account the visual tabulator length.
+ *
+ * @param seq the string to measure
+ * @return the visual length of <code>seq</code>
+ */
+ public static int computeVisualLength(CharSequence seq, int tablen) {
+ int size= 0;
+
+ for (int i= 0; i < seq.length(); i++) {
+ char ch= seq.charAt(i);
+ if (ch == '\t') {
+ if (tablen != 0)
+ size += tablen - size % tablen;
+ // else: size stays the same
+ } else {
+ size++;
+ }
+ }
+ return size;
+ }
+
+ /**
+ * Returns the indentation of the line <code>line</code> in <code>document</code>.
+ * The returned string may contain pairs of leading slashes that are considered
+ * part of the indentation.
+ *
+ * @param document the document
+ * @param line the line
+ * @param indentInsideLineComments option whether to indent inside line comments starting at column 0
+ * @return the indentation of <code>line</code> in <code>document</code>
+ * @throws BadLocationException if the document is changed concurrently
+ */
+ public static String getCurrentIndent(IDocument document, int line, boolean indentInsideLineComments) throws BadLocationException {
+ IRegion region= document.getLineInformation(line);
+ int from= region.getOffset();
+ int endOffset= region.getOffset() + region.getLength();
+
+ int to= from;
+ if (indentInsideLineComments) {
+ // go behind line comments
+ while (to < endOffset - 2 && document.get(to, 2).equals(SLASHES))
+ to += 2;
+ }
+
+ while (to < endOffset) {
+ char ch= document.getChar(to);
+ if (!Character.isWhitespace(ch))
+ break;
+ to++;
+ }
+
+ return document.get(from, to - from);
+ }
+
+ private static int getLeftMostLine(IDocument document, ILineRange lines, int tabSize, boolean indentInsideLineComments) throws BadLocationException {
+ int numberOfLines= lines.getNumberOfLines();
+ int first= lines.getStartLine();
+ int minLine= -1;
+ int minIndent= Integer.MAX_VALUE;
+ for (int line= 0; line < numberOfLines; line++) {
+ int length= computeVisualLength(getCurrentIndent(document, line + first, indentInsideLineComments), tabSize);
+ if (length < minIndent && document.getLineLength(line + first) > 0) {
+ minIndent= length;
+ minLine= line;
+ }
+ }
+ return minLine;
+ }
+
+ private static IndentResult reuseOrCreateToken(IndentResult token, int numberOfLines) {
+ if (token == null)
+ token= new IndentResult(new boolean[numberOfLines]);
+ else if (token.commentLinesAtColumnZero == null)
+ token.commentLinesAtColumnZero= new boolean[numberOfLines];
+ else if (token.commentLinesAtColumnZero.length != numberOfLines) {
+ boolean[] commentBooleans= new boolean[numberOfLines];
+ System.arraycopy(token.commentLinesAtColumnZero, 0, commentBooleans, 0, Math.min(numberOfLines, token.commentLinesAtColumnZero.length));
+ token.commentLinesAtColumnZero= commentBooleans;
+ }
+ return token;
+ }
+
+ /**
+ * Indents a single line using the heuristic scanner. Multiline comments are
+ * indented as specified by the <code>CCommentAutoIndentStrategy</code>.
+ *
+ * @param document the document
+ * @param line the line to be indented
+ * @param indenter the C indenter
+ * @param scanner the heuristic scanner
+ * @param commentLines the indent token comment booleans
+ * @param lineIndex the zero-based line index
+ * @param indentInsideLineComments option whether to indent inside line comments
+ * starting at column 0
+ * @return <code>true</code> if the document was modified,
+ * <code>false</code> if not
+ * @throws BadLocationException if the document got changed concurrently
+ */
+ private static boolean indentLine(IDocument document, int line, STPIndenter indenter,
+ STPHeuristicScanner scanner, boolean[] commentLines, int lineIndex, int tabSize,
+ boolean indentInsideLineComments) throws BadLocationException {
+ IRegion currentLine= document.getLineInformation(line);
+ final int offset= currentLine.getOffset();
+ int wsStart= offset; // where we start searching for non-WS; after the "//" in single line comments
+
+ String indent= null;
+ if (offset < document.getLength()) {
+ ITypedRegion partition= TextUtilities.getPartition(document, STPPartitionScanner.STP_PARTITIONING, offset, true);
+ ITypedRegion startingPartition= TextUtilities.getPartition(document, STPPartitionScanner.STP_PARTITIONING, offset, false);
+ String type= partition.getType();
+ if (type.equals(STPPartitionScanner.STP_COMMENT)) {
+ indent= computeCommentIndent(document, line, scanner, startingPartition);
+ } else if (startingPartition.getType().equals(STPPartitionScanner.STP_CONDITIONAL)) {
+ indent= computePreprocessorIndent(document, line, startingPartition);
+ } else if (!commentLines[lineIndex] && startingPartition.getOffset() == offset && startingPartition.getType().equals(STPPartitionScanner.STP_COMMENT)) {
+ return false;
+ }
+ }
+
+ // standard C code indentation
+ if (indent == null) {
+ StringBuilder computed= indenter.computeIndentation(offset);
+ if (computed != null)
+ indent= computed.toString();
+ else
+ indent= ""; //$NON-NLS-1$
+ }
+
+ // change document:
+ // get current white space
+ int lineLength= currentLine.getLength();
+ int end= scanner.findNonWhitespaceForwardInAnyPartition(wsStart, offset + lineLength);
+ if (end == STPHeuristicScanner.NOT_FOUND)
+ end= offset + lineLength;
+ int length= end - offset;
+ String currentIndent= document.get(offset, length);
+
+ // memorize the fact that a line is a single line comment (but not at column 0) and should be treated like code
+ // as opposed to commented out code, which should keep its slashes at column 0
+ // if 'indentInsideLineComments' is false, all comment lines are indented with the code
+ if (length > 0 || !indentInsideLineComments) {
+ ITypedRegion partition= TextUtilities.getPartition(document, STPPartitionScanner.STP_PARTITIONING, end, false);
+ if (partition.getOffset() == end && STPPartitionScanner.STP_COMMENT.equals(partition.getType())) {
+ commentLines[lineIndex]= true;
+ }
+ }
+
+ // only change the document if it is a real change
+ if (!indent.equals(currentIndent)) {
+ document.replace(offset, length, indent);
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Computes and returns the indentation for a source line.
+ *
+ * @param document the document
+ * @param line the line in document
+ * @param indenter the C indenter
+ * @param scanner the scanner
+ * @return the indent, never <code>null</code>
+ * @throws BadLocationException
+ */
+ public static String computeIndent(IDocument document, int line, STPIndenter indenter, STPHeuristicScanner scanner) throws BadLocationException {
+ IRegion currentLine= document.getLineInformation(line);
+ final int offset= currentLine.getOffset();
+
+ String indent= null;
+ if (offset < document.getLength()) {
+ ITypedRegion partition= TextUtilities.getPartition(document, STPPartitionScanner.STP_PARTITIONING, offset, true);
+ ITypedRegion startingPartition= TextUtilities.getPartition(document, STPPartitionScanner.STP_PARTITIONING, offset, false);
+ String type= partition.getType();
+ if (type.equals(STPPartitionScanner.STP_COMMENT)) {
+ indent= computeCommentIndent(document, line, scanner, startingPartition);
+ } else if (startingPartition.getType().equals(STPPartitionScanner.STP_CONDITIONAL)) {
+ indent= computePreprocessorIndent(document, line, startingPartition);
+ }
+ }
+
+ // standard C code indentation
+ if (indent == null) {
+ StringBuilder computed= indenter.computeIndentation(offset);
+ if (computed != null)
+ indent= computed.toString();
+ else
+ indent= new String();
+ }
+ return indent;
+ }
+
+ /**
+ * Computes and returns the indentation for a block comment line.
+ *
+ * @param document the document
+ * @param line the line in document
+ * @param scanner the scanner
+ * @param partition the comment partition
+ * @return the indent, or <code>null</code> if not computable
+ * @throws BadLocationException
+ */
+ public static String computeCommentIndent(IDocument document, int line, STPHeuristicScanner scanner, ITypedRegion partition) throws BadLocationException {
+ if (line == 0) // impossible - the first line is never inside a comment
+ return null;
+
+ // don't make any assumptions if the line does not start with \s*\* - it might be
+ // commented out code, for which we don't want to change the indent
+ final IRegion lineInfo= document.getLineInformation(line);
+ final int lineStart= lineInfo.getOffset();
+ final int lineLength= lineInfo.getLength();
+ final int lineEnd= lineStart + lineLength;
+ int nonWS= scanner.findNonWhitespaceForwardInAnyPartition(lineStart, lineEnd);
+ if (nonWS == STPHeuristicScanner.NOT_FOUND || document.getChar(nonWS) != '*') {
+ if (nonWS == STPHeuristicScanner.NOT_FOUND)
+ return document.get(lineStart, lineLength);
+ return document.get(lineStart, nonWS - lineStart);
+ }
+
+ // take the indent from the previous line and reuse
+ IRegion previousLine= document.getLineInformation(line - 1);
+ int previousLineStart= previousLine.getOffset();
+ int previousLineLength= previousLine.getLength();
+ int previousLineEnd= previousLineStart + previousLineLength;
+
+ StringBuilder buf= new StringBuilder();
+ int previousLineNonWS= scanner.findNonWhitespaceForwardInAnyPartition(previousLineStart, previousLineEnd);
+ if (previousLineNonWS == STPHeuristicScanner.NOT_FOUND || document.getChar(previousLineNonWS) != '*') {
+ // align with the comment start if the previous line is not an asterix line
+ previousLine= document.getLineInformationOfOffset(partition.getOffset());
+ previousLineStart= previousLine.getOffset();
+ previousLineLength= previousLine.getLength();
+ previousLineEnd= previousLineStart + previousLineLength;
+ previousLineNonWS= scanner.findNonWhitespaceForwardInAnyPartition(previousLineStart, previousLineEnd);
+ if (previousLineNonWS == STPHeuristicScanner.NOT_FOUND)
+ previousLineNonWS= previousLineEnd;
+
+ // add the initial space
+ // TODO this may be controlled by a formatter preference in the future
+ buf.append(' ');
+ }
+
+ String indentation= document.get(previousLineStart, previousLineNonWS - previousLineStart);
+ buf.insert(0, indentation);
+ return buf.toString();
+ }
+
+ /**
+ * Computes and returns the indentation for a preprocessor line.
+ *
+ * @param document the document
+ * @param line the line in document
+ * @param partition the comment partition
+ * @return the indent, or <code>null</code> if not computable
+ * @throws BadLocationException
+ */
+ public static String computePreprocessorIndent(IDocument document, int line, ITypedRegion partition)
+ throws BadLocationException {
+ int ppFirstLine= document.getLineOfOffset(partition.getOffset());
+ if (line == ppFirstLine) {
+ return ""; //$NON-NLS-1$
+ }
+ STPHeuristicScanner ppScanner= new STPHeuristicScanner(document, STPPartitionScanner.STP_CONDITIONAL, partition.getType());
+ STPIndenter ppIndenter= new STPIndenter(document, ppScanner);
+ if (line == ppFirstLine + 1) {
+ return ppIndenter.createReusingIndent(new StringBuilder(), ppIndenter.getContinuationLineIndent(), 0).toString();
+ }
+ StringBuilder computed= ppIndenter.computeIndentation(document.getLineOffset(line), false);
+ if (computed != null) {
+ return computed.toString();
+ }
+ // take the indent from the previous line and reuse
+ IRegion previousLine= document.getLineInformation(line - 1);
+ int previousLineStart= previousLine.getOffset();
+ int previousLineLength= previousLine.getLength();
+ int previousLineEnd= previousLineStart + previousLineLength;
+
+ int previousLineNonWS= ppScanner.findNonWhitespaceForwardInAnyPartition(previousLineStart, previousLineEnd);
+ String previousIndent= document.get(previousLineStart, previousLineNonWS - previousLineStart);
+ computed= new StringBuilder(previousIndent);
+ return computed.toString();
+ }
+
+ /**
+ * Extends the string with whitespace to match displayed width.
+ * @param prefix add to this string
+ * @param displayedWidth the desired display width
+ * @param tabWidth the configured tab width
+ * @param useSpaces whether to use spaces only
+ */
+ public static String changePrefix(String prefix, int displayedWidth, int tabWidth, boolean useSpaces) {
+ int column = computeVisualLength(prefix, tabWidth);
+ if (column > displayedWidth) {
+ return prefix;
+ }
+ final StringBuilder buffer = new StringBuilder(prefix);
+ appendIndent(buffer, displayedWidth, tabWidth, useSpaces, column);
+ return buffer.toString();
+ }
+
+ /**
+ * Appends whitespace to given buffer such that its visual length equals the given width.
+ * @param buffer the buffer to add whitespace to
+ * @param width the desired visual indent width
+ * @param tabWidth the configured tab width
+ * @param useSpaces whether tabs should be substituted by spaces
+ * @param startColumn the column where to start measurement
+ * @return StringBuilder
+ */
+ private static StringBuilder appendIndent(StringBuilder buffer, int width, int tabWidth, boolean useSpaces, int startColumn) {
+ assert tabWidth > 0;
+ int tabStop = startColumn - startColumn % tabWidth;
+ int tabs = useSpaces ? 0 : (width-tabStop) / tabWidth;
+ for (int i = 0; i < tabs; ++i) {
+ buffer.append('\t');
+ tabStop += tabWidth;
+ startColumn = tabStop;
+ }
+ int spaces = width - startColumn;
+ for (int i = 0; i < spaces; ++i) {
+ buffer.append(' ');
+ }
+ return buffer;
+ }
+
+}
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/OptimizedReplaceEdit.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/OptimizedReplaceEdit.java
new file mode 100644
index 0000000000..d9459d1a9a
--- /dev/null
+++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/OptimizedReplaceEdit.java
@@ -0,0 +1,30 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2011, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ * Sergey Prigogin (Google)
+ * Red Hat Inc. - modified for use in SystemTap
+ *******************************************************************************/
+package org.eclipse.linuxtools.internal.systemtap.ui.ide.editors.stp;
+
+public class OptimizedReplaceEdit {
+ int offset;
+ int length;
+ String replacement;
+
+ public OptimizedReplaceEdit(int offset, int length, CharSequence replacement) {
+ this.offset = offset;
+ this.length = length;
+ this.replacement = replacement.toString();
+ }
+
+ @Override
+ public String toString() {
+ return "(" + this.offset + ", length " + this.length + " :>" + this.replacement + "<"; //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$//$NON-NLS-4$
+ }
+}
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPAlignment.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPAlignment.java
new file mode 100644
index 0000000000..8289b7782c
--- /dev/null
+++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPAlignment.java
@@ -0,0 +1,516 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ * Sergey Prigogin (Google)
+ *******************************************************************************/
+package org.eclipse.linuxtools.internal.systemtap.ui.ide.editors.stp;
+
+import java.util.Arrays;
+
+/**
+ * Alignment management
+ *
+ * @since 4.0
+ */
+public class STPAlignment {
+ // Alignment names.
+ public static final String ASSIGNMENT_EXPRESSION = "assignmentExpression"; //$NON-NLS-1$
+ public static final String BINARY_EXPRESSION = "binaryExpression"; //$NON-NLS-1$
+ public static final String COMPACT_IF = "compactIf"; //$NON-NLS-1$
+ public static final String CONDITIONAL_EXPRESSION = "conditionalExpression"; //$NON-NLS-1$
+ public static final String CONDITIONAL_EXPRESSION_CHAIN = "conditionalExpressionChain"; //$NON-NLS-1$
+ public static final String DECLARATION_INITIALIZER = "declarationInitializer"; //$NON-NLS-1$
+ public static final String DESIGNATED_INITIALIZER = "designatedInitializer"; //$NON-NLS-1$
+ public static final String EXCEPTION_SPECIFICATION = "exceptionSpecification"; //$NON-NLS-1$
+ public static final String FIELD_REFERENCE = "fieldReference"; //$NON-NLS-1$
+ public static final String FOR = "for"; //$NON-NLS-1$
+ public static final String LIST_ELEMENTS_PREFIX = "listElements_"; //$NON-NLS-1$
+ public static final String MACRO_ARGUMENTS = "macroArguments"; //$NON-NLS-1$
+ public static final String OVERLOADED_LEFT_SHIFT_CHAIN = "overloadedLeftShiftChain"; //$NON-NLS-1$
+ public static final String TRAILING_TEXT = "trailingText"; //$NON-NLS-1$
+
+ /** The name of the alignment */
+ public String name;
+
+ /** Link to the enclosing alignment. */
+ public STPAlignment enclosing;
+
+ /** Start location of this alignment. */
+ public STPLocation location;
+
+ /**
+ * Tail formatter is an encapsulation mechanism for formatting of the trailing text that should
+ * be kept together with the last element of a list.
+ */
+ public Runnable tailFormatter;
+
+ // Indentation management
+ public int fragmentIndex;
+ public int fragmentCount;
+ public int[] fragmentIndentations;
+ public boolean needRedoColumnAlignment;
+
+ // Chunk management
+ public int chunkStartIndex;
+ public int chunkKind;
+
+ // Break management
+ public int originalIndentationLevel;
+ public int breakIndentationLevel;
+ public int alternativeBreakIndentationLevel;
+ public int[] fragmentBreaks;
+ public boolean wasSplit;
+ public int currentFragmentStartLine;
+
+ public final STPScribe scribe;
+
+ /*
+ * Alignment modes
+ */
+ public static final int M_FORCE = 1; // if bit set, then alignment will be non-optional (default is optional)
+ public static final int M_INDENT_ON_COLUMN = 2; // if bit set, broken fragments will be aligned on current location column (default is to break at current indentation level)
+ public static final int M_INDENT_BY_ONE = 4; // if bit set, broken fragments will be indented one level below current (not using continuation indentation)
+
+ // Split modes can be combined either with M_FORCE or M_INDENT_ON_COLUMN
+
+ /** foobar(#fragment1, #fragment2, <ul>
+ * <li> #fragment3, #fragment4 </li>
+ * </ul>
+ */
+ public static final int M_COMPACT_SPLIT = 16; // fill each line with all possible fragments
+
+ /** foobar(<ul>
+ * <li> #fragment1, #fragment2, </li>
+ * <li> #fragment5, #fragment4, </li>
+ * </ul>
+ */
+ public static final int M_COMPACT_FIRST_BREAK_SPLIT = 32; // compact mode, but will first try to break before first fragment
+
+ /** foobar(<ul>
+ * <li> #fragment1, </li>
+ * <li> #fragment2, </li>
+ * <li> #fragment3 </li>
+ * <li> #fragment4, </li>
+ * </ul>
+ */
+ public static final int M_ONE_PER_LINE_SPLIT = 32 + 16; // one fragment per line
+
+ /**
+ * foobar(<ul>
+ * <li> #fragment1, </li>
+ * <li> #fragment2, </li>
+ * <li> #fragment3, </li>
+ * <li> #fragment4, </li>
+ * </ul>
+ */
+ public static final int M_NEXT_SHIFTED_SPLIT = 64; // one fragment per line, subsequent are indented further
+
+ /** foobar(#fragment1, <ul>
+ * <li> #fragment2, </li>
+ * <li> #fragment3 </li>
+ * <li> #fragment4, </li>
+ * </ul>
+ */
+ public static final int M_NEXT_PER_LINE_SPLIT = 64 + 16; // one per line, except first fragment (if possible)
+
+ //64+32
+ //64+32+16
+
+ // Mode controlling column alignments
+ /**
+ * <table BORDER COLS=4 WIDTH="100%" >
+ * <tr><td>#fragment1A</td> <td>#fragment2A</td> <td>#fragment3A</td> <td>#very-long-fragment4A</td></tr>
+ * <tr><td>#fragment1B</td> <td>#long-fragment2B</td> <td>#fragment3B</td> <td>#fragment4B</td></tr>
+ * <tr><td>#very-long-fragment1C</td> <td>#fragment2C</td> <td>#fragment3C</td> <td>#fragment4C</td></tr>
+ * </table>
+ */
+ public static final int M_MULTICOLUMN = 256; // fragments are on same line, but multiple line of fragments will be aligned vertically
+
+ public static final int M_NO_ALIGNMENT = 0;
+
+ public int mode;
+
+ public static final int SPLIT_MASK = M_ONE_PER_LINE_SPLIT | M_NEXT_SHIFTED_SPLIT | M_COMPACT_SPLIT | M_COMPACT_FIRST_BREAK_SPLIT | M_NEXT_PER_LINE_SPLIT;
+
+ // Alignment tie-break rules - when split is needed, will decide whether innermost/outermost alignment is to be chosen
+ public static final int R_OUTERMOST = 1;
+ public static final int R_INNERMOST = 2;
+ public int tieBreakRule;
+
+ // Alignment effects on a per fragment basis
+ public static final int BREAK_NOT_ALLOWED = -1;
+ public static final int NONE = 0;
+ public static final int BREAK = 2;
+
+ // Chunk kind
+ public static final int CHUNK_FIELD = 1;
+ public static final int CHUNK_METHOD = 2;
+ public static final int CHUNK_TYPE = 3;
+ public static final int CHUNK_ENUM = 4;
+
+ // Location to align and break on.
+ public STPAlignment(String name, int mode, int tieBreakRule, STPScribe scribe, int fragmentCount,
+ int sourceRestart, int continuationIndent) {
+ this.name = name;
+ this.location = new STPLocation(scribe, sourceRestart);
+ this.mode = mode;
+ this.tieBreakRule = tieBreakRule;
+ this.fragmentCount = fragmentCount;
+ this.scribe = scribe;
+ this.originalIndentationLevel = this.scribe.indentationLevel;
+ this.wasSplit = false;
+ this.fragmentIndentations = new int[this.fragmentCount];
+ this.fragmentBreaks = new int[this.fragmentCount];
+ Arrays.fill(this.fragmentBreaks, (this.mode & M_FORCE) == 0 ? BREAK_NOT_ALLOWED : NONE);
+ this.currentFragmentStartLine = this.scribe.line;
+
+ int currentColumn = this.location.outputColumn;
+ if (currentColumn == 1) {
+ currentColumn = this.location.outputIndentationLevel + 1;
+ }
+
+ // Initialize the break indentation level, using modes and continuationIndentationLevel
+ // preference.
+ final int indentSize = this.scribe.indentationSize;
+
+ if ((mode & M_INDENT_ON_COLUMN) != 0) {
+ // Indent broken fragments at next indentation level, based on current column
+ this.breakIndentationLevel = this.scribe.getNextIndentationLevel(currentColumn);
+ this.alternativeBreakIndentationLevel =
+ this.location.outputIndentationLevel + continuationIndent * indentSize;
+ } else {
+ int baseIndentationLevel = this.location.outputIndentationLevel;
+ if (name != TRAILING_TEXT && this.scribe.currentAlignment != null &&
+ (this.scribe.currentAlignment.mode & M_INDENT_ON_COLUMN) != 0 &&
+ this.scribe.currentAlignment.fragmentCount > 1) {
+ baseIndentationLevel = this.scribe.currentAlignment.breakIndentationLevel;
+ }
+ if ((mode & M_INDENT_BY_ONE) != 0) {
+ // Indent broken fragments exactly one level deeper than current indentation
+ this.breakIndentationLevel = baseIndentationLevel + indentSize;
+ } else {
+ this.breakIndentationLevel = baseIndentationLevel + continuationIndent * indentSize;
+ }
+ this.alternativeBreakIndentationLevel = this.breakIndentationLevel;
+ }
+
+ // Check for forced alignments
+ if ((this.mode & M_FORCE) != 0) {
+ this.fragmentBreaks[this.fragmentIndex] = NONE;
+ couldBreak();
+ }
+ }
+
+ public boolean checkChunkStart(int kind, int startIndex, int sourceRestart) {
+ if (this.chunkKind != kind) {
+ this.chunkKind = kind;
+
+ // When redoing same chunk alignment, must not reset
+ if (startIndex != this.chunkStartIndex) {
+ this.chunkStartIndex = startIndex;
+ this.location.update(this.scribe, sourceRestart);
+ reset();
+ }
+ return true;
+ }
+ return false;
+ }
+
+ public void checkColumn() {
+ if ((this.mode & M_MULTICOLUMN) != 0) {
+ int currentIndentation = this.scribe.getNextIndentationLevel(this.scribe.column + (this.scribe.needSpace ? 1 : 0));
+ int fragmentIndentation = this.fragmentIndentations[this.fragmentIndex];
+ if (currentIndentation > fragmentIndentation) {
+ this.fragmentIndentations[this.fragmentIndex] = currentIndentation;
+ if (fragmentIndentation != 0) {
+ for (int i = this.fragmentIndex + 1; i < this.fragmentCount; i++) {
+ this.fragmentIndentations[i] = 0;
+ }
+ this.needRedoColumnAlignment = true;
+ }
+ }
+ // Backtrack only once all fragments got checked
+ if (this.needRedoColumnAlignment && this.fragmentIndex == this.fragmentCount - 1) { // alignment too small
+// if (CodeFormatterVisitor.DEBUG) {
+// System.out.println("ALIGNMENT TOO SMALL");
+// System.out.println(this);
+// }
+ this.needRedoColumnAlignment = false;
+ int relativeDepth = 0;
+ STPAlignment targetAlignment = this.scribe.memberAlignment;
+ while (targetAlignment != null) {
+ if (targetAlignment == this) {
+ throw new AlignmentException(AlignmentException.ALIGN_TOO_SMALL, relativeDepth);
+ }
+ targetAlignment = targetAlignment.enclosing;
+ relativeDepth++;
+ }
+ }
+ }
+ }
+
+ public boolean couldBreak() {
+ int i;
+ switch (mode & SPLIT_MASK) {
+ /* # aligned fragment
+ * foo(
+ * #AAAAA, #BBBBB,
+ * #CCCC);
+ */
+ case M_COMPACT_FIRST_BREAK_SPLIT:
+ if (this.fragmentBreaks[0] == NONE) {
+ if ((this.mode & M_INDENT_ON_COLUMN) != 0) {
+ if (this.breakIndentationLevel <= this.alternativeBreakIndentationLevel) {
+ // Does not make sense to break here unless indentation is reduced.
+ break;
+ }
+ // Change break indentation level and erase previously created breaks.
+ this.breakIndentationLevel = this.alternativeBreakIndentationLevel;
+ eraseExistingBreaks(0);
+ }
+ this.fragmentBreaks[0] = BREAK;
+ this.fragmentIndentations[0] = this.breakIndentationLevel;
+ return wasSplit = true;
+ }
+ i = this.fragmentIndex;
+ do {
+ if (this.fragmentBreaks[i] == NONE) {
+ this.fragmentBreaks[i] = BREAK;
+ this.fragmentIndentations[i] = this.breakIndentationLevel;
+ return wasSplit = true;
+ }
+ } while (--i >= 0);
+ break;
+ /* # aligned fragment
+ * foo(#AAAAA, #BBBBB,
+ * #CCCC);
+ */
+ case M_COMPACT_SPLIT:
+ i = this.fragmentIndex;
+ do {
+ if (this.fragmentBreaks[i] == NONE) {
+ if ((this.mode & M_INDENT_ON_COLUMN) != 0 && isFirstBreakableFragment(i)) {
+ if (this.breakIndentationLevel <= this.alternativeBreakIndentationLevel) {
+ // Does not make sense to break here unless indentation is reduced.
+ break;
+ }
+ // Change break indentation level and erase previously created breaks.
+ this.breakIndentationLevel = this.alternativeBreakIndentationLevel;
+ eraseExistingBreaks(i);
+ }
+ this.fragmentBreaks[i] = BREAK;
+ this.fragmentIndentations[i] = this.breakIndentationLevel;
+ return wasSplit = true;
+ }
+ } while ((this.fragmentBreaks[i] != BREAK || (this.mode & M_INDENT_ON_COLUMN) != 0) && --i >= 0);
+ break;
+
+ /* # aligned fragment
+ * foo(
+ * #AAAAA,
+ * #BBBBB,
+ * #CCCC);
+ */
+ case M_NEXT_SHIFTED_SPLIT:
+ if (this.fragmentBreaks[0] == NONE) {
+ this.fragmentBreaks[0] = BREAK;
+ this.fragmentIndentations[0] = this.breakIndentationLevel;
+ for (i = 1; i < this.fragmentCount; i++) {
+ this.fragmentBreaks[i] = BREAK;
+ this.fragmentIndentations[i] =
+ this.breakIndentationLevel + this.scribe.indentationSize;
+ }
+ return wasSplit = true;
+ }
+ break;
+
+ /* # aligned fragment
+ * foo(
+ * #AAAAA,
+ * #BBBBB,
+ * #CCCC);
+ */
+ case M_ONE_PER_LINE_SPLIT:
+ if (this.fragmentBreaks[0] == NONE) {
+ for (i = 0; i < this.fragmentCount; i++) {
+ this.fragmentBreaks[i] = BREAK;
+ this.fragmentIndentations[i] = this.breakIndentationLevel;
+ }
+ return wasSplit = true;
+ }
+ break;
+ /* # aligned fragment
+ * foo(#AAAAA,
+ * #BBBBB,
+ * #CCCC);
+ */
+ case M_NEXT_PER_LINE_SPLIT:
+ if (this.fragmentBreaks[0] != BREAK) {
+ if (this.fragmentCount > 1 && this.fragmentBreaks[1] == NONE) {
+ if ((this.mode & M_INDENT_ON_COLUMN) != 0) {
+ this.fragmentIndentations[0] = this.breakIndentationLevel;
+ }
+ for (i = 1; i < this.fragmentCount; i++) {
+ this.fragmentBreaks[i] = BREAK;
+ this.fragmentIndentations[i] = this.breakIndentationLevel;
+ }
+ return wasSplit = true;
+ }
+ }
+ break;
+ }
+ return false; // Cannot split better
+ }
+
+ private boolean isFirstBreakableFragment(int i) {
+ while (--i >= 0) {
+ if (this.fragmentBreaks[i] != BREAK_NOT_ALLOWED)
+ return false;
+ }
+ return true;
+ }
+
+ private void eraseExistingBreaks(int startFragmentIndex) {
+ for (int j = startFragmentIndex + 1; j < this.fragmentIndentations.length; j++) {
+ if (this.fragmentBreaks[j] == BREAK) {
+ this.fragmentBreaks[j] = NONE;
+ this.fragmentIndentations[j] = 0;
+ }
+ }
+ }
+
+ public STPAlignment getAlignment(String targetName) {
+ if (targetName.equals(this.name)) return this;
+ if (this.enclosing == null) return null;
+
+ return this.enclosing.getAlignment(targetName);
+ }
+
+ public void alignFragment(int fragmentIndex) {
+ this.fragmentIndex= fragmentIndex;
+ if (this.fragmentBreaks[fragmentIndex] == BREAK_NOT_ALLOWED) {
+ this.fragmentBreaks[fragmentIndex] = NONE; // Allow line break.
+ }
+ switch (this.mode & SPLIT_MASK) {
+ case STPAlignment.M_NEXT_PER_LINE_SPLIT:
+ case STPAlignment.M_ONE_PER_LINE_SPLIT:
+ for (int i = fragmentIndex + 1; i < this.fragmentBreaks.length; i++) {
+ if (this.fragmentBreaks[i] == BREAK_NOT_ALLOWED) {
+ this.fragmentBreaks[i] = NONE; // Allow line break.
+ }
+ }
+ break;
+ }
+ checkColumn();
+ performFragmentEffect();
+ }
+
+ // Performs alignment effect for current fragment.
+ public void performFragmentEffect() {
+ if ((this.mode & M_MULTICOLUMN) == 0) {
+ switch (this.mode & SPLIT_MASK) {
+ case STPAlignment.M_COMPACT_SPLIT:
+ case STPAlignment.M_COMPACT_FIRST_BREAK_SPLIT:
+ case STPAlignment.M_NEXT_PER_LINE_SPLIT:
+ case STPAlignment.M_NEXT_SHIFTED_SPLIT:
+ case STPAlignment.M_ONE_PER_LINE_SPLIT:
+ break;
+ default:
+ return;
+ }
+ }
+
+ if ((this.mode & M_INDENT_ON_COLUMN) != 0 && this.fragmentIndex > 0 &&
+ this.scribe.line > currentFragmentStartLine) {
+ // The previous fragment spans multiple line. Put the current fragment on a new line.
+ this.fragmentBreaks[this.fragmentIndex] = BREAK;
+ this.fragmentIndentations[this.fragmentIndex] = this.breakIndentationLevel;
+ wasSplit = true;
+ }
+ if (this.fragmentBreaks[this.fragmentIndex] == BREAK) {
+ this.scribe.startNewLine();
+ }
+ if (this.fragmentIndentations[this.fragmentIndex] > 0) {
+ this.scribe.indentationLevel = this.fragmentIndentations[this.fragmentIndex];
+ }
+ currentFragmentStartLine = this.scribe.line;
+ }
+
+ // test whether this is an 'indent-on-column' type alignment and aligns on the given column
+ public boolean isIndentOnColumn(int column) {
+ return (mode & M_INDENT_ON_COLUMN) != 0 && breakIndentationLevel == column - 1;
+ }
+
+ // reset fragment indentation/break status
+ public void reset() {
+ if (fragmentCount > 0) {
+ this.fragmentIndentations = new int[this.fragmentCount];
+ this.fragmentBreaks = new int[this.fragmentCount];
+ }
+
+ // check for forced alignments
+ if ((mode & M_FORCE) != 0) {
+ couldBreak();
+ }
+ }
+
+ public void toFragmentsString(StringBuffer buffer) {
+ // default implementation
+ }
+
+ @Override
+ public String toString() {
+ StringBuffer buffer = new StringBuffer(10);
+ buffer
+ .append(getClass().getName())
+ .append(':')
+ .append("<name: ") //$NON-NLS-1$
+ .append(this.name)
+ .append(">"); //$NON-NLS-1$
+ if (this.enclosing != null) {
+ buffer
+ .append("<enclosingName: ") //$NON-NLS-1$
+ .append(this.enclosing.name)
+ .append('>');
+ }
+ buffer.append('\n');
+
+ for (int i = 0; i < this.fragmentCount; i++) {
+ buffer
+ .append(" - fragment ") //$NON-NLS-1$
+ .append(i)
+ .append(": ") //$NON-NLS-1$
+ .append("<break: ") //$NON-NLS-1$
+ .append(this.fragmentBreaks[i] > 0 ? "YES" : "NO") //$NON-NLS-1$ //$NON-NLS-2$
+ .append(">") //$NON-NLS-1$
+ .append("<indent: ") //$NON-NLS-1$
+ .append(this.fragmentIndentations[i])
+ .append(">\n"); //$NON-NLS-1$
+ }
+ buffer.append('\n');
+ return buffer.toString();
+ }
+
+ public void update() {
+ for (int i = 1; i < this.fragmentCount; i++) {
+ if (this.fragmentBreaks[i] == BREAK) {
+ this.fragmentIndentations[i] = this.breakIndentationLevel;
+ }
+ }
+ }
+
+ public boolean isWrapped() {
+ for (int i = 0, max = this.fragmentCount; i < max; i++) {
+ if (this.fragmentBreaks[i] == BREAK) {
+ return true;
+ }
+ }
+ return false;
+ }
+}
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPAutoEditStrategy.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPAutoEditStrategy.java
index ee200c67bc..0f46486c9d 100644
--- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPAutoEditStrategy.java
+++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPAutoEditStrategy.java
@@ -10,29 +10,92 @@
*******************************************************************************/
package org.eclipse.linuxtools.internal.systemtap.ui.ide.editors.stp;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.DefaultIndentLineAutoEditStrategy;
+import org.eclipse.jface.text.Document;
import org.eclipse.jface.text.DocumentCommand;
+import org.eclipse.jface.text.DocumentRewriteSession;
+import org.eclipse.jface.text.DocumentRewriteSessionType;
import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITypedRegion;
+import org.eclipse.jface.text.TextUtilities;
+import org.eclipse.jface.text.rules.FastPartitioner;
+import org.eclipse.linuxtools.internal.systemtap.ui.ide.IDEPlugin;
+import org.eclipse.linuxtools.internal.systemtap.ui.ide.editors.stp.STPIndenter.MatchMode;
/**
* Very basic auto edit strategy simply completing opening with closing brackets and quotes.
*/
public class STPAutoEditStrategy extends
DefaultIndentLineAutoEditStrategy {
+ private static final String LINE_COMMENT= "//"; //$NON-NLS-1$
+ private boolean fCloseBrace = true;
+
+ private String fPartitioning;
+ private IProject fProject;
+
+ public STPAutoEditStrategy(String fPartitioning, IProject project) {
+ this.fPartitioning = fPartitioning;
+ this.fProject = project;
+ }
+
+ /**
+ * Returns the block balance, i.e. zero if the blocks are balanced at
+ * <code>offset</code>, a negative number if there are more closing than opening
+ * braces, and a positive number if there are more opening than closing braces.
+ *
+ * @param document
+ * @param offset
+ * @param partitioning
+ * @return the block balance
+ */
+ private static int getBlockBalance(IDocument document, int offset, String partitioning) {
+ if (offset < 1)
+ return -1;
+ if (offset >= document.getLength())
+ return 1;
+
+ int begin = offset;
+ int end = offset - 1;
+
+ STPHeuristicScanner scanner = new STPHeuristicScanner(document);
+
+ while (true) {
+ begin = scanner.findOpeningPeer(begin - 1, '{', '}');
+ end = scanner.findClosingPeer(end + 1, '{', '}');
+ if (begin == -1 && end == -1)
+ return 0;
+ if (begin == -1)
+ return -1;
+ if (end == -1)
+ return 1;
+ }
+ }
+
@Override
public void customizeDocumentCommand(IDocument document,
DocumentCommand command) {
boolean modified = false;
- if (command.text.equals("\"")) { //$NON-NLS-1$
+ boolean isNewLine= command.length == 0 && command.text != null
+ && isLineDelimiter(document, command.text);
+ if (isNewLine) {
+ smartIndentAfterNewLine(document, command);
+ } else if (command.text.length() == 1) {
+ smartIndentOnKeypress(document, command);
+ } else if (command.text.length() > 1
+ && command.text.trim().length() != 0) {
+ smartPaste(document, command); // no smart backspace for paste
+ }
+ if (command.text.equals("\"") && !inStringOrComment(document, command)) { //$NON-NLS-1$
command.text = "\"\""; //$NON-NLS-1$
modified = true;
- } else if (command.text.equals("(")){ //$NON-NLS-1$
+ } else if (command.text.equals("(") && !inStringOrComment(document, command)) { //$NON-NLS-1$
command.text = "()"; //$NON-NLS-1$
modified = true;
- } else if (command.text.equals("{")) { //$NON-NLS-1$
- command.text = "{}"; //$NON-NLS-1$
- modified = true;
- } else if (command.text.equals("[")) { //$NON-NLS-1$
+ } else if (command.text.equals("[") && !inStringOrComment(document, command)) { //$NON-NLS-1$
command.text = "[]"; //$NON-NLS-1$
modified = true;
}
@@ -44,4 +107,979 @@ public class STPAutoEditStrategy extends
super.customizeDocumentCommand(document, command);
}
+
+ private boolean inStringOrComment(IDocument d, DocumentCommand c) {
+ int docLength = d.getLength();
+ if (c.offset == -1 || docLength == 0)
+ return false;
+ try {
+ ITypedRegion partition= TextUtilities.getPartition(d, fPartitioning, c.offset, false);
+ if (c.offset > 0 &&
+ STPPartitionScanner.STP_COMMENT.equals(partition.getType())) {
+ return true;
+ }
+ IRegion lineInfo = d.getLineInformationOfOffset(c.offset);
+ int offset = lineInfo.getOffset();
+ boolean inChar = false;
+ boolean inString = false;
+ boolean inComment = false;
+ for (int i = offset; i < c.offset; ++i) {
+ char ch = d.getChar(i);
+ switch (ch) {
+ case '\"':
+ if (!inChar)
+ inString = !inString;
+ break;
+ case '\'':
+ if (!inString)
+ inChar = !inChar;
+ break;
+ case '\\':
+ ++i;
+ break;
+ case '/':
+ if (!inString && !inChar) {
+ ch = d.getChar(i + 1);
+ if (ch == '/')
+ return true; // We have a line comment
+ else if (ch == '*')
+ inComment = true;
+ }
+ break;
+ case '#':
+ if (!inString && !inChar)
+ return true;
+ break;
+ case '*':
+ if (!inString && !inChar) {
+ if (inComment) {
+ ch = d.getChar(i + 1);
+ if (ch == '/')
+ inComment = false;
+ }
+ }
+ break;
+ }
+ }
+ return inString || inChar || inComment;
+
+ } catch (BadLocationException e) {
+ IDEPlugin.log(e);
+ }
+ return false;
+ }
+
+
+ private void smartIndentAfterNewLine(IDocument d, DocumentCommand c) {
+ int docLength = d.getLength();
+ if (c.offset == -1 || docLength == 0)
+ return;
+
+ int addIndent= 0;
+ STPHeuristicScanner scanner= new STPHeuristicScanner(d);
+ try {
+ ITypedRegion partition= TextUtilities.getPartition(d, fPartitioning, c.offset, false);
+ if (STPPartitionScanner.STP_CONDITIONAL.equals(partition.getType()) && c.offset > 0 && d.getChar(c.offset-1) == '\\') {
+ scanner = new STPHeuristicScanner(d, fPartitioning, STPPartitionScanner.STP_CONDITIONAL);
+ addIndent= 1;
+ }
+
+ int line = d.getLineOfOffset(c.offset);
+ IRegion reg = d.getLineInformation(line);
+ int start = reg.getOffset();
+ int lineEnd = start + reg.getLength();
+
+ StringBuilder indent= null;
+ STPIndenter indenter= new STPIndenter(d, scanner, fProject);
+ indent= indenter.computeIndentation(c.offset);
+ if (indent == null) {
+ indent= new StringBuilder();
+ }
+ if (addIndent > 0 && indent.length() == 0) {
+ indent= indenter.createReusingIndent(indent, addIndent, 0);
+ }
+
+ StringBuilder buf = new StringBuilder(c.text + indent);
+ int contentStart = findEndOfWhiteSpace(d, c.offset, lineEnd);
+ c.length = Math.max(contentStart - c.offset, 0);
+
+ // insert closing brace on new line after an unclosed opening brace
+ if (getBracketCount(d, start, c.offset, true) > 0 && fCloseBrace && !isClosedBrace(d, c.offset, c.length)) {
+ c.caretOffset = c.offset + buf.length();
+ c.shiftsCaret = false;
+
+ // copy old content of line behind insertion point to new line
+ // unless we think we are inserting an anonymous type definition
+ if (c.offset == 0 || !(computeAnonymousPosition(d, c.offset - 1, fPartitioning, lineEnd) != -1)) {
+ if (lineEnd - contentStart > 0) {
+ c.length = lineEnd - c.offset;
+ buf.append(d.get(contentStart, lineEnd - contentStart).toCharArray());
+ }
+ }
+
+ buf.append(TextUtilities.getDefaultLineDelimiter(d));
+ StringBuilder reference = null;
+ int nonWS = findEndOfWhiteSpace(d, start, lineEnd);
+ if (nonWS < c.offset && d.getChar(nonWS) == '{')
+ reference = new StringBuilder(d.get(start, nonWS - start));
+ else
+ reference = indenter.getReferenceIndentation(c.offset);
+ if (reference != null)
+ buf.append(reference);
+ buf.append('}');
+ int bound= c.offset > 200 ? c.offset - 200 : STPHeuristicScanner.UNBOUND;
+ int bracePos = scanner.findOpeningPeer(c.offset - 1, bound, '{', '}');
+ if (bracePos != STPHeuristicScanner.NOT_FOUND) {
+ if (scanner.looksLikeCompositeTypeDefinitionBackward(bracePos, bound) ||
+ scanner.previousToken(bracePos - 1, bound) == STPSymbols.TokenEQUAL) {
+ buf.append(';');
+ }
+ }
+ }
+ // insert extra line upon new line between two braces
+ else if (c.offset > start && contentStart < lineEnd && d.getChar(contentStart) == '}') {
+ int firstCharPos = scanner.findNonWhitespaceBackward(c.offset - 1, start);
+ if (firstCharPos != STPHeuristicScanner.NOT_FOUND && d.getChar(firstCharPos) == '{') {
+ c.caretOffset = c.offset + buf.length();
+ c.shiftsCaret = false;
+
+ StringBuilder reference = null;
+ int nonWS = findEndOfWhiteSpace(d, start, lineEnd);
+ if (nonWS < c.offset && d.getChar(nonWS) == '{')
+ reference = new StringBuilder(d.get(start, nonWS - start));
+ else
+ reference = indenter.getReferenceIndentation(c.offset);
+
+ buf.append(TextUtilities.getDefaultLineDelimiter(d));
+
+ if (reference != null)
+ buf.append(reference);
+ }
+ }
+ c.text = buf.toString();
+
+ } catch (BadLocationException e) {
+ IDEPlugin.log(e);
+ }
+ }
+
+ private void smartIndentUponE(IDocument doc, DocumentCommand c) {
+ if (c.offset < 4 || doc.getLength() == 0)
+ return;
+
+ try {
+ String content = doc.get(c.offset - 3, 3);
+ if (content.equals("els")) { //$NON-NLS-1$
+ STPHeuristicScanner scanner = new STPHeuristicScanner(doc);
+ int p = c.offset - 3;
+
+ // current line
+ int line = doc.getLineOfOffset(p);
+ int lineOffset = doc.getLineOffset(line);
+
+ // make sure we don't have any leading comments etc.
+ if (doc.get(lineOffset, p - lineOffset).trim().length() != 0)
+ return;
+
+ // Line of last C code
+ int pos = scanner.findNonWhitespaceBackward(p - 1, STPHeuristicScanner.UNBOUND);
+ if (pos == -1)
+ return;
+ int lastLine = doc.getLineOfOffset(pos);
+
+ // Only shift if the last C line is further up and is a braceless block candidate
+ if (lastLine < line) {
+ STPIndenter indenter = new STPIndenter(doc, scanner, fProject);
+ int ref = indenter.findReferencePosition(p, true, MatchMode.REGULAR);
+ if (ref == STPHeuristicScanner.NOT_FOUND)
+ return;
+ int refLine = doc.getLineOfOffset(ref);
+ String indent = getIndentOfLine(doc, refLine);
+
+ if (indent != null) {
+ c.text = indent.toString() + "else"; //$NON-NLS-1$
+ c.length += c.offset - lineOffset;
+ c.offset = lineOffset;
+ }
+ }
+
+ return;
+ }
+
+ if (content.equals("cas")) { //$NON-NLS-1$
+ STPHeuristicScanner scanner = new STPHeuristicScanner(doc);
+ int p = c.offset - 3;
+
+ // current line
+ int line = doc.getLineOfOffset(p);
+ int lineOffset = doc.getLineOffset(line);
+
+ // make sure we don't have any leading comments etc.
+ if (doc.get(lineOffset, p - lineOffset).trim().length() != 0)
+ return;
+
+ // Line of last C code
+ int pos = scanner.findNonWhitespaceBackward(p - 1, STPHeuristicScanner.UNBOUND);
+ if (pos == -1)
+ return;
+ int lastLine = doc.getLineOfOffset(pos);
+
+ // Only shift if the last C line is further up and is a braceless block candidate
+ if (lastLine < line) {
+ STPIndenter indenter = new STPIndenter(doc, scanner, fProject);
+ int ref = indenter.findReferencePosition(p, false, MatchMode.MATCH_CASE);
+ if (ref == STPHeuristicScanner.NOT_FOUND)
+ return;
+ int refLine = doc.getLineOfOffset(ref);
+ int nextToken = scanner.nextToken(ref, STPHeuristicScanner.UNBOUND);
+ String indent;
+ if (nextToken == STPSymbols.TokenCASE || nextToken == STPSymbols.TokenDEFAULT)
+ indent = getIndentOfLine(doc, refLine);
+ else // at the brace of the switch
+ indent = indenter.computeIndentation(p).toString();
+
+ if (indent != null) {
+ c.text = indent.toString() + "case"; //$NON-NLS-1$
+ c.length += c.offset - lineOffset;
+ c.offset = lineOffset;
+ }
+ }
+
+ return;
+ }
+ } catch (BadLocationException e) {
+ IDEPlugin.log(e);
+ }
+ }
+ /**
+ * Computes an insert position for an opening brace if <code>offset</code> maps to a position in
+ * <code>document</code> with a expression in parenthesis that will take a block after the closing parenthesis.
+ *
+ * @param document the document being modified
+ * @param offset the offset of the caret position, relative to the line start.
+ * @param partitioning the document partitioning
+ * @param max the max position
+ * @return an insert position relative to the line start if <code>line</code> contains a parenthesized expression that can be followed by a block, -1 otherwise
+ */
+ private static int computeAnonymousPosition(IDocument document, int offset, String partitioning, int max) {
+ // find the opening parenthesis for every closing parenthesis on the current line after offset
+ // return the position behind the closing parenthesis if it looks like a method declaration
+ // or an expression for an if, while, for, catch statement
+
+ STPHeuristicScanner scanner = new STPHeuristicScanner(document);
+ int pos = offset;
+ int length = max;
+ int scanTo = scanner.scanForward(pos, length, '}');
+ if (scanTo == -1)
+ scanTo = length;
+
+ int closingParen = findClosingParenToLeft(scanner, pos) - 1;
+
+ while (true) {
+ int startScan = closingParen + 1;
+ closingParen = scanner.scanForward(startScan, scanTo, ')');
+ if (closingParen == -1)
+ break;
+
+ int openingParen = scanner.findOpeningPeer(closingParen - 1, '(', ')');
+
+ // no way an expression at the beginning of the document can mean anything
+ if (openingParen < 1)
+ break;
+
+ // only select insert positions for parenthesis currently embracing the caret
+ if (openingParen > pos)
+ continue;
+ }
+
+ return -1;
+ }
+
+ /**
+ * Finds a closing parenthesis to the left of <code>position</code> in document, where that parenthesis is only
+ * separated by whitespace from <code>position</code>. If no such parenthesis can be found, <code>position</code> is returned.
+ *
+ * @param scanner the C heuristic scanner set up on the document
+ * @param position the first character position in <code>document</code> to be considered
+ * @return the position of a closing parenthesis left to <code>position</code> separated only by whitespace, or <code>position</code> if no parenthesis can be found
+ */
+ private static int findClosingParenToLeft(STPHeuristicScanner scanner, int position) {
+ if (position < 1)
+ return position;
+
+ if (scanner.previousToken(position - 1, STPHeuristicScanner.UNBOUND) == STPSymbols.TokenRPAREN)
+ return scanner.getPosition() + 1;
+ return position;
+ }
+
+ private boolean isClosedBrace(IDocument document, int offset, int length) {
+ return getBlockBalance(document, offset, fPartitioning) <= 0;
+ }
+
+ private void smartIndentOnKeypress(IDocument document, DocumentCommand command) {
+ switch (command.text.charAt(0)) {
+ case '}':
+ smartIndentAfterClosingBracket(document, command);
+ break;
+ case '{':
+ smartIndentAfterOpeningBracket(document, command);
+ break;
+ case 'e':
+ smartIndentUponE(document, command);
+ break;
+// case ':':
+// smartIndentAfterColumn(document, command);
+// break;
+ case '#':
+ smartIndentAfterHash(document, command);
+ break;
+ case '\"':
+ smartInsertCloseChar(document, command, '\"');
+ break;
+ case ')':
+ smartInsertCloseChar(document, command, ')');
+ break;
+ case ']':
+ smartInsertCloseChar(document, command, ']');
+ break;
+ }
+ }
+
+ /**
+ * A closing char (e.g. right paren ')') is being inserted. If one already exists
+ * at current location in the document, skip over it and don't do an
+ * insert.
+ *
+ * @param d - document
+ * @param c - insert text
+ * @param ch - closing char being inserted
+ */
+ private void smartInsertCloseChar(IDocument d, DocumentCommand c, char ch) {
+ if (c.offset < 1 || d.getLength() == 0)
+ return;
+
+ try {
+ if (d.getChar(c.offset) == ch) {
+ int backslashCount = 0;
+ int prevOffset = c.offset - 1;
+ // Look backwards for backslashes. We will ignore if there are even number
+ while (prevOffset > 0 && d.getChar(prevOffset) == '\\') {
+ --prevOffset;
+ ++backslashCount;
+ }
+ if ((backslashCount & 1) == 0) {
+ c.text = ""; //$NON-NLS-1$
+ c.offset++;
+ }
+ }
+ } catch (BadLocationException e) {
+ IDEPlugin.log(e);
+ }
+
+ }
+
+ private void smartIndentAfterHash(IDocument doc, DocumentCommand c) {
+ try {
+ ITypedRegion partition= TextUtilities.getPartition(doc, fPartitioning, c.offset, false);
+ if (IDocument.DEFAULT_CONTENT_TYPE.equals(partition.getType())) {
+ IRegion startLine= doc.getLineInformationOfOffset(c.offset);
+ String indent= doc.get(startLine.getOffset(), c.offset - startLine.getOffset());
+ if (indent.trim().length() == 0) {
+ c.offset -= indent.length();
+ c.length += indent.length();
+ }
+ }
+ } catch (BadLocationException e) {
+ IDEPlugin.log(e);
+ }
+ }
+
+ private void smartIndentAfterOpeningBracket(IDocument d, DocumentCommand c) {
+ if (c.offset < 1 || d.getLength() == 0)
+ return;
+
+ int p = (c.offset == d.getLength() ? c.offset - 1 : c.offset);
+
+ try {
+ STPHeuristicScanner scanner= new STPHeuristicScanner(d);
+ ITypedRegion partition= TextUtilities.getPartition(d, fPartitioning, p, false);
+ if (STPPartitionScanner.STP_CONDITIONAL.equals(partition.getType())) {
+ scanner = new STPHeuristicScanner(d, fPartitioning, STPPartitionScanner.STP_CONDITIONAL);
+ }
+ // current line
+ int line = d.getLineOfOffset(c.offset);
+ int lineOffset = d.getLineOffset(line);
+
+ // make sure we don't have any leading comments etc.
+ if (!d.get(lineOffset, c.offset - lineOffset).trim().isEmpty())
+ return;
+
+ // Line of last C code
+ int pos = scanner.findNonWhitespaceBackward(p, STPHeuristicScanner.UNBOUND);
+ if (pos == -1)
+ return;
+ int lastLine = d.getLineOfOffset(pos);
+
+ // Only shift if the last C line is further up and is a braceless block candidate
+ if (lastLine < line) {
+ STPIndenter indenter = new STPIndenter(d, scanner, fProject);
+ StringBuilder indent = indenter.computeIndentation(p, true);
+ String toDelete = d.get(lineOffset, c.offset - lineOffset);
+ if (indent != null && !indent.toString().equals(toDelete)) {
+ c.text = indent.append(c.text).toString();
+ c.length += c.offset - lineOffset;
+ c.offset = lineOffset;
+ }
+ }
+ } catch (BadLocationException e) {
+ IDEPlugin.log(e);
+ }
+ }
+
+ private boolean isLineDelimiter(IDocument document, String text) {
+ String[] delimiters = document.getLegalLineDelimiters();
+ if (delimiters != null)
+ return TextUtilities.equals(delimiters, text) > -1;
+ return false;
+ }
+
+ private int getBracketCount(IDocument d, int start, int end, boolean ignoreCloseBrackets) throws BadLocationException {
+ int bracketcount = 0;
+ while (start < end) {
+ char curr = d.getChar(start);
+ start++;
+ switch (curr) {
+ case '#' :
+ if (start < end) {
+ // '#'-comment: nothing to do anymore on this line
+ start = end;
+ }
+ break;
+ case '/' :
+ if (start < end) {
+ char next = d.getChar(start);
+ if (next == '*') {
+ // a comment starts, advance to the comment end
+ start = getCommentEnd(d, start + 1, end);
+ } else if (next == '/') {
+ // '//'-comment: nothing to do anymore on this line
+ start = end;
+ }
+ }
+ break;
+ case '*' :
+ if (start < end) {
+ char next = d.getChar(start);
+ if (next == '/') {
+ // we have been in a comment: forget what we read before
+ bracketcount = 0;
+ start++;
+ }
+ }
+ break;
+ case '{' :
+ bracketcount++;
+ ignoreCloseBrackets = false;
+ break;
+ case '}' :
+ if (!ignoreCloseBrackets) {
+ bracketcount--;
+ }
+ break;
+ case '"' :
+ case '\'' :
+ start = getStringEnd(d, start, end, curr);
+ break;
+ default :
+ }
+ }
+ return bracketcount;
+ }
+
+
+ // ----------- bracket counting ------------------------------------------------------
+
+ private int getCommentEnd(IDocument d, int pos, int end) throws BadLocationException {
+ while (pos < end) {
+ char curr = d.getChar(pos);
+ pos++;
+ if (curr == '*') {
+ if (pos < end && d.getChar(pos) == '/') {
+ return pos + 1;
+ }
+ }
+ }
+ return end;
+ }
+
+ private String getIndentOfLine(IDocument d, int line) throws BadLocationException {
+ if (line > -1) {
+ int start = d.getLineOffset(line);
+ int end = start + d.getLineLength(line) - 1;
+ int whiteend = findEndOfWhiteSpace(d, start, end);
+ return d.get(start, whiteend - start);
+ }
+ return ""; //$NON-NLS-1$
+ }
+
+ private int getStringEnd(IDocument d, int pos, int end, char ch) throws BadLocationException {
+ while (pos < end) {
+ char curr = d.getChar(pos);
+ pos++;
+ if (curr == '\\') {
+ // ignore escaped characters
+ pos++;
+ } else if (curr == ch) {
+ return pos;
+ }
+ }
+ return end;
+ }
+ private void smartIndentAfterClosingBracket(IDocument d, DocumentCommand c) {
+ if (c.offset == -1 || d.getLength() == 0)
+ return;
+
+ try {
+ int p = (c.offset == d.getLength() ? c.offset - 1 : c.offset);
+ int line = d.getLineOfOffset(p);
+ int start = d.getLineOffset(line);
+ int whiteend = findEndOfWhiteSpace(d, start, c.offset);
+
+ STPHeuristicScanner scanner= new STPHeuristicScanner(d);
+ ITypedRegion partition= TextUtilities.getPartition(d, fPartitioning, p, false);
+ if (STPPartitionScanner.STP_CONDITIONAL.equals(partition.getType())) {
+ scanner = new STPHeuristicScanner(d, fPartitioning, STPPartitionScanner.STP_CONDITIONAL);
+ }
+ STPIndenter indenter = new STPIndenter(d, scanner, fProject);
+
+ // shift only when line does not contain any text up to the closing bracket
+ if (whiteend == c.offset) {
+ // evaluate the line with the opening bracket that matches out closing bracket
+ int reference = indenter.findReferencePosition(c.offset, false, MatchMode.MATCH_BRACE);
+ int indLine = d.getLineOfOffset(reference);
+ if (indLine != -1 && indLine != line) {
+ // take the indent of the found line
+ StringBuilder replaceText = new StringBuilder(getIndentOfLine(d, indLine));
+ // add the rest of the current line including the just added close bracket
+ replaceText.append(d.get(whiteend, c.offset - whiteend));
+ replaceText.append(c.text);
+ // modify document command
+ c.length += c.offset - start;
+ c.offset = start;
+ c.text = replaceText.toString();
+ }
+ }
+ } catch (BadLocationException e) {
+ IDEPlugin.log(e);
+ }
+ }
+
+ /**
+ * Installs a C partitioner with <code>document</code>.
+ *
+ * @param document the document
+ */
+ private static void installPartitioner(Document document) {
+ String[] types= new String[] {
+ IDocument.DEFAULT_CONTENT_TYPE,
+ STPPartitionScanner.STP_COMMENT,
+ STPPartitionScanner.STP_CONDITIONAL,
+ };
+ FastPartitioner partitioner= new FastPartitioner(new STPPartitionScanner(), types);
+ partitioner.connect(document);
+ document.setDocumentPartitioner(STPPartitionScanner.STP_PARTITIONING, partitioner);
+ }
+
+ /**
+ * Installs a C partitioner with <code>document</code>.
+ *
+ * @param document the document
+ */
+ private static void removePartitioner(Document document) {
+ document.setDocumentPartitioner(STPPartitionScanner.STP_PARTITIONING, null);
+ }
+
+ private void smartPaste(IDocument document, DocumentCommand command) {
+ int newOffset= command.offset;
+ int newLength= command.length;
+ String newText= command.text;
+
+ try {
+ STPHeuristicScanner scanner= new STPHeuristicScanner(document);
+ STPIndenter indenter= new STPIndenter(document, scanner, fProject);
+ int offset= newOffset;
+
+ // reference position to get the indent from
+ int refOffset= indenter.findReferencePosition(offset);
+ if (refOffset == STPHeuristicScanner.NOT_FOUND)
+ return;
+ int peerOffset= getPeerPosition(document, command);
+ peerOffset= indenter.findReferencePosition(peerOffset);
+ if (peerOffset == STPHeuristicScanner.NOT_FOUND)
+ return;
+ refOffset= Math.min(refOffset, peerOffset);
+
+ // eat any WS before the insertion to the beginning of the line
+ int firstLine= 1; // don't format the first line per default, as it has other content before it
+ IRegion line= document.getLineInformationOfOffset(offset);
+ String notSelected= document.get(line.getOffset(), offset - line.getOffset());
+ if (notSelected.trim().length() == 0) {
+ newLength += notSelected.length();
+ newOffset= line.getOffset();
+ firstLine= 0;
+ }
+
+ // Prefix: the part we need for formatting but won't paste.
+ // Take up to 100 previous lines to preserve enough context.
+ int firstPrefixLine= Math.max(document.getLineOfOffset(refOffset) - 100, 0);
+ int prefixOffset= document.getLineInformation(firstPrefixLine).getOffset();
+ String prefix= document.get(prefixOffset, newOffset - prefixOffset);
+
+ // Handle the indentation computation inside a temporary document
+ Document temp= new Document(prefix + newText);
+ DocumentRewriteSession session= temp.startRewriteSession(DocumentRewriteSessionType.STRICTLY_SEQUENTIAL);
+ scanner= new STPHeuristicScanner(temp);
+ indenter= new STPIndenter(temp, scanner, fProject);
+ installPartitioner(temp);
+
+ // Indent the first and second line
+ // compute the relative indentation difference from the second line
+ // (as the first might be partially selected) and use the value to
+ // indent all other lines.
+ boolean isIndentDetected= false;
+ StringBuilder addition= new StringBuilder();
+ int insertLength= 0;
+ int first= document.computeNumberOfLines(prefix) + firstLine; // don't format first line
+ int lines= temp.getNumberOfLines();
+ boolean changed= false;
+ boolean indentInsideLineComments= IndentUtil.indentInsideLineComments(fProject);
+
+ for (int l= first; l < lines; l++) { // we don't change the number of lines while adding indents
+ IRegion r= temp.getLineInformation(l);
+ int lineOffset= r.getOffset();
+ int lineLength= r.getLength();
+
+ if (lineLength == 0) // don't modify empty lines
+ continue;
+
+ if (!isIndentDetected) {
+ // indent the first pasted line
+ String current= IndentUtil.getCurrentIndent(temp, l, indentInsideLineComments);
+ StringBuilder correct= new StringBuilder(IndentUtil.computeIndent(temp, l, indenter, scanner));
+
+ insertLength= subtractIndent(correct, current, addition);
+ // workaround for bug 181139
+ if (/*l != first && */temp.get(lineOffset, lineLength).trim().length() != 0) {
+ isIndentDetected= true;
+ if (insertLength == 0) {
+ // no adjustment needed, bail out
+ if (firstLine == 0) {
+ // but we still need to adjust the first line
+ command.offset= newOffset;
+ command.length= newLength;
+ if (changed)
+ break; // still need to get the leading indent of the first line
+ }
+ return;
+ }
+ removePartitioner(temp);
+ } else {
+ changed= insertLength != 0;
+ }
+ }
+
+ // relatively indent all pasted lines
+ if (insertLength > 0)
+ addIndent(temp, l, addition, indentInsideLineComments);
+ else if (insertLength < 0)
+ cutIndent(temp, l, -insertLength, indentInsideLineComments);
+ }
+
+ temp.stopRewriteSession(session);
+ newText= temp.get(prefix.length(), temp.getLength() - prefix.length());
+
+ command.offset= newOffset;
+ command.length= newLength;
+ command.text= newText;
+ } catch (BadLocationException e) {
+ IDEPlugin.log(e);
+ }
+ }
+ /**
+ * Computes the difference of two indentations and returns the difference in
+ * length of current and correct. If the return value is positive, <code>addition</code>
+ * is initialized with a substring of that length of <code>correct</code>.
+ *
+ * @param correct the correct indentation
+ * @param current the current indentation (migth contain non-whitespace)
+ * @param difference a string buffer - if the return value is positive, it will be cleared and set to the substring of <code>current</code> of that length
+ * @return the difference in lenght of <code>correct</code> and <code>current</code>
+ */
+ private int subtractIndent(CharSequence correct, CharSequence current, StringBuilder difference) {
+ int c1= computeVisualLength(correct);
+ int c2= computeVisualLength(current);
+ int diff= c1 - c2;
+ if (diff <= 0)
+ return diff;
+
+ difference.setLength(0);
+ int len= 0, i= 0;
+ while (len < diff) {
+ char c= correct.charAt(i++);
+ difference.append(c);
+ len += computeVisualLength(c);
+ }
+
+ return diff;
+ }
+
+ /**
+ * Indents line <code>line</code> in <code>document</code> with <code>indent</code>.
+ * Leaves leading comment signs alone.
+ *
+ * @param document the document
+ * @param line the line
+ * @param indent the indentation to insert
+ * @param indentInsideLineComments option whether to indent inside line comments starting at column 0
+ * @throws BadLocationException on concurrent document modification
+ */
+ private static void addIndent(Document document, int line, CharSequence indent, boolean indentInsideLineComments) throws BadLocationException {
+ IRegion region= document.getLineInformation(line);
+ int insert= region.getOffset();
+ int endOffset= region.getOffset() + region.getLength();
+
+ if (indentInsideLineComments) {
+ // go behind line comments
+ while (insert < endOffset - 2 && document.get(insert, 2).equals(LINE_COMMENT))
+ insert += 2;
+ }
+
+ // insert indent
+ document.replace(insert, 0, indent.toString());
+ }
+
+ /**
+ * Cuts the visual equivalent of <code>toDelete</code> characters out of the
+ * indentation of line <code>line</code> in <code>document</code>. Leaves
+ * leading comment signs alone.
+ *
+ * @param document the document
+ * @param line the line
+ * @param toDelete the number of space equivalents to delete.
+ * @param indentInsideLineComments option whether to indent inside line comments starting at column 0
+ * @throws BadLocationException on concurrent document modification
+ */
+ private void cutIndent(Document document, int line, int toDelete, boolean indentInsideLineComments) throws BadLocationException {
+ IRegion region= document.getLineInformation(line);
+ int from= region.getOffset();
+ int endOffset= region.getOffset() + region.getLength();
+
+ if (indentInsideLineComments) {
+ // go behind line comments
+ while (from < endOffset - 2 && document.get(from, 2).equals(LINE_COMMENT))
+ from += 2;
+ }
+
+ int to= from;
+ while (toDelete > 0 && to < endOffset) {
+ char ch= document.getChar(to);
+ if (!Character.isWhitespace(ch))
+ break;
+ toDelete -= computeVisualLength(ch);
+ if (toDelete >= 0)
+ to++;
+ else
+ break;
+ }
+
+ document.replace(from, to - from, null);
+ }
+
+ /**
+ * Returns the visual length of a given <code>CharSequence</code> taking into
+ * account the visual tabulator length.
+ *
+ * @param seq the string to measure
+ * @return the visual length of <code>seq</code>
+ */
+ private int computeVisualLength(CharSequence seq) {
+ int size= 0;
+ int tablen= getVisualTabLengthPreference();
+
+ for (int i= 0; i < seq.length(); i++) {
+ char ch= seq.charAt(i);
+ if (ch == '\t') {
+ if (tablen != 0)
+ size += tablen - size % tablen;
+ // else: size stays the same
+ } else {
+ size++;
+ }
+ }
+ return size;
+ }
+
+ /**
+ * Returns the visual length of a given character taking into
+ * account the visual tabulator length.
+ *
+ * @param ch the character to measure
+ * @return the visual length of <code>ch</code>
+ */
+ private int computeVisualLength(char ch) {
+ if (ch == '\t')
+ return getVisualTabLengthPreference();
+ return 1;
+ }
+
+ /**
+ * The preference setting for the visual tabulator display.
+ *
+ * @return the number of spaces displayed for a tabulator in the editor
+ */
+ private int getVisualTabLengthPreference() {
+ return CodeFormatterUtil.getTabWidth(fProject);
+ }
+
+ private int getPeerPosition(IDocument document, DocumentCommand command) {
+ if (document.getLength() == 0)
+ return 0;
+ /*
+ * Search for scope closers in the pasted text and find their opening peers
+ * in the document.
+ */
+ Document pasted= new Document(command.text);
+ installPartitioner(pasted);
+ int firstPeer= command.offset;
+
+ STPHeuristicScanner pScanner= new STPHeuristicScanner(pasted);
+ STPHeuristicScanner dScanner= new STPHeuristicScanner(document);
+
+ // add scope relevant after context to peer search
+ int afterToken= dScanner.nextToken(command.offset + command.length, STPHeuristicScanner.UNBOUND);
+ try {
+ switch (afterToken) {
+ case STPSymbols.TokenRBRACE:
+ pasted.replace(pasted.getLength(), 0, "}"); //$NON-NLS-1$
+ break;
+ case STPSymbols.TokenRPAREN:
+ pasted.replace(pasted.getLength(), 0, ")"); //$NON-NLS-1$
+ break;
+ case STPSymbols.TokenRBRACKET:
+ pasted.replace(pasted.getLength(), 0, "]"); //$NON-NLS-1$
+ break;
+ }
+ } catch (BadLocationException e) {
+ // cannot happen
+ Assert.isTrue(false);
+ }
+
+ int pPos= 0; // paste text position (increasing from 0)
+ int dPos= Math.max(0, command.offset - 1); // document position (decreasing from paste offset)
+ while (true) {
+ int token= pScanner.nextToken(pPos, STPHeuristicScanner.UNBOUND);
+ pPos= pScanner.getPosition();
+ switch (token) {
+ case STPSymbols.TokenLBRACE:
+ case STPSymbols.TokenLBRACKET:
+ case STPSymbols.TokenLPAREN:
+ pPos= skipScope(pScanner, pPos, token);
+ if (pPos == STPHeuristicScanner.NOT_FOUND)
+ return firstPeer;
+ break; // closed scope -> keep searching
+ case STPSymbols.TokenRBRACE:
+ int peer= dScanner.findOpeningPeer(dPos, '{', '}');
+ dPos= peer - 1;
+ if (peer == STPHeuristicScanner.NOT_FOUND)
+ return firstPeer;
+ firstPeer= peer;
+ break; // keep searching
+ case STPSymbols.TokenRBRACKET:
+ peer= dScanner.findOpeningPeer(dPos, '[', ']');
+ dPos= peer - 1;
+ if (peer == STPHeuristicScanner.NOT_FOUND)
+ return firstPeer;
+ firstPeer= peer;
+ break; // keep searching
+ case STPSymbols.TokenRPAREN:
+ peer= dScanner.findOpeningPeer(dPos, '(', ')');
+ dPos= peer - 1;
+ if (peer == STPHeuristicScanner.NOT_FOUND)
+ return firstPeer;
+ firstPeer= peer;
+ break; // keep searching
+
+ case STPSymbols.TokenCASE:
+ case STPSymbols.TokenDEFAULT:
+ {
+ STPIndenter indenter= new STPIndenter(document, dScanner, fProject);
+ peer= indenter.findReferencePosition(dPos, false, MatchMode.MATCH_CASE);
+ if (peer == STPHeuristicScanner.NOT_FOUND)
+ return firstPeer;
+ firstPeer= peer;
+ }
+ break; // keep searching
+
+ case STPSymbols.TokenPUBLIC:
+ case STPSymbols.TokenPROTECTED:
+ case STPSymbols.TokenPRIVATE:
+ {
+ STPIndenter indenter= new STPIndenter(document, dScanner, fProject);
+ peer= indenter.findReferencePosition(dPos, false, MatchMode.MATCH_ACCESS_SPECIFIER);
+ if (peer == STPHeuristicScanner.NOT_FOUND)
+ return firstPeer;
+ firstPeer= peer;
+ }
+ break; // keep searching
+
+ case STPSymbols.TokenEOF:
+ return firstPeer;
+ default:
+ // keep searching
+ }
+ }
+ }
+ /**
+ * Skips the scope opened by <code>token</code> in <code>document</code>,
+ * returns either the position of the
+ * @param pos
+ * @param token
+ * @return the position after the scope
+ */
+ private static int skipScope(STPHeuristicScanner scanner, int pos, int token) {
+ int openToken= token;
+ int closeToken;
+ switch (token) {
+ case STPSymbols.TokenLPAREN:
+ closeToken= STPSymbols.TokenRPAREN;
+ break;
+ case STPSymbols.TokenLBRACKET:
+ closeToken= STPSymbols.TokenRBRACKET;
+ break;
+ case STPSymbols.TokenLBRACE:
+ closeToken= STPSymbols.TokenRBRACE;
+ break;
+ default:
+ Assert.isTrue(false);
+ return -1; // dummy
+ }
+
+ int depth= 1;
+ int p= pos;
+
+ while (true) {
+ int tok= scanner.nextToken(p, STPHeuristicScanner.UNBOUND);
+ p= scanner.getPosition();
+
+ if (tok == openToken) {
+ depth++;
+ } else if (tok == closeToken) {
+ depth--;
+ if (depth == 0)
+ return p + 1;
+ } else if (tok == STPSymbols.TokenEOF) {
+ return STPHeuristicScanner.NOT_FOUND;
+ }
+ }
+ }
} \ No newline at end of file
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPCompletionProcessor.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPCompletionProcessor.java
index f6e9d0c025..269f468cfc 100644
--- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPCompletionProcessor.java
+++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPCompletionProcessor.java
@@ -15,7 +15,9 @@ import java.util.ArrayList;
import java.util.Arrays;
import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.BadPartitioningException;
import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IDocumentExtension3;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.ITextHover;
import org.eclipse.jface.text.ITextViewer;
@@ -81,11 +83,26 @@ public class STPCompletionProcessor implements IContentAssistProcessor, ITextHov
public ICompletionProposal[] computeCompletionProposals(IDocument document, int offset){
ITypedRegion partition = null;
+ boolean useGlobal = false;
try {
- partition = document.getPartition(offset);
+ partition =
+ ((IDocumentExtension3) document).getPartition(STPProbeScanner.STP_PROBE_PARTITIONING, offset, false);
+ if (partition.getOffset() == offset) {
+ if (partition.getType() != IDocument.DEFAULT_CONTENT_TYPE && partition.getType() != STPProbeScanner.STP_PROBE) {
+ if (offset > 0) {
+ ITypedRegion prevPartition =
+ ((IDocumentExtension3) document).getPartition(STPProbeScanner.STP_PROBE_PARTITIONING, offset - 1, false);
+ useGlobal = prevPartition.getType() == IDocument.DEFAULT_CONTENT_TYPE;
+ } else {
+ useGlobal = true;
+ }
+ }
+ }
} catch (BadLocationException e1) {
return NO_COMPLETIONS;
+ } catch (BadPartitioningException e) {
+ return NO_COMPLETIONS;
}
String prefix = ""; //$NON-NLS-1$
@@ -112,14 +129,9 @@ public class STPCompletionProcessor implements IContentAssistProcessor, ITextHov
return getProbeCompletionList(prefix, offset);
}
- // In the global scope return global keyword completion.
- if (partition.getType() == IDocument.DEFAULT_CONTENT_TYPE ){
- return getGlobalKeywordCompletion(prefix, offset);
- }
-
// If inside a probe return probe variable completions and functions
// which can be called.
- if (partition.getType() == STPPartitionScanner.STP_PROBE){
+ if (partition.getType() == STPProbeScanner.STP_PROBE) {
ICompletionProposal[] variableCompletions = getProbeVariableCompletions(document, offset, prefix);
ICompletionProposal[] functionCompletions = getFunctionCompletions(offset, prefix);
@@ -129,6 +141,9 @@ public class STPCompletionProcessor implements IContentAssistProcessor, ITextHov
completions.addAll(Arrays.asList(functionCompletions));
return completions.toArray(new ICompletionProposal[0]);
+ } else if (partition.getType() == IDocument.DEFAULT_CONTENT_TYPE || useGlobal) {
+ // In the global scope return global keyword completion.
+ return getGlobalKeywordCompletion(prefix, offset);
}
return NO_COMPLETIONS;
@@ -180,6 +195,8 @@ public class STPCompletionProcessor implements IContentAssistProcessor, ITextHov
return result;
} catch (BadLocationException e) {
return NO_COMPLETIONS;
+ } catch (BadPartitioningException e) {
+ return NO_COMPLETIONS;
}
}
@@ -191,11 +208,14 @@ public class STPCompletionProcessor implements IContentAssistProcessor, ITextHov
* @param offset
* @return the probe name
* @throws BadLocationException
+ * @throws BadPartitioningException
*/
- private String getProbe(IDocument document, int offset) throws BadLocationException{
+ private String getProbe(IDocument document, int offset) throws BadLocationException, BadPartitioningException{
String probePoint = null;
- ITypedRegion partition = document.getPartition(offset);
+ ITypedRegion partition
+ = ((IDocumentExtension3)document).getPartition(STPProbeScanner.STP_PROBE_PARTITIONING,
+ offset, false);
String probe = document.get(partition.getOffset(), partition.getLength());
// make sure that we are inside a probe
@@ -475,14 +495,19 @@ public class STPCompletionProcessor implements IContentAssistProcessor, ITextHov
documentation = TapsetLibrary.getDocumentation("tapset::" + keyword); //$NON-NLS-1$
}
- if (textViewer.getDocument().getPartition(hoverRegion.getOffset())
- .getType() == STPPartitionScanner.STP_PROBE) {
+ IDocument document = textViewer.getDocument();
+ ITypedRegion partition =
+ ((IDocumentExtension3)document).getPartition(STPProbeScanner.STP_PROBE_PARTITIONING,
+ hoverRegion.getOffset(), false);
+ if (partition.getType() == STPProbeScanner.STP_PROBE) {
String probe = getProbe(textViewer.getDocument(), hoverRegion.getOffset());
documentation = TapsetLibrary.getDocumentation("probe::" + probe + "::"+ keyword); //$NON-NLS-1$ //$NON-NLS-2$
}
} catch (BadLocationException e) {
// Bad hover location; just ignore it.
+ } catch (BadPartitioningException e) {
+ // Bad hover scenario, just ignore it.
}
return documentation;
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPConfiguration.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPConfiguration.java
index 0b357b74f1..ca8b230f38 100644
--- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPConfiguration.java
+++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPConfiguration.java
@@ -52,8 +52,7 @@ public class STPConfiguration extends SourceViewerConfiguration {
return new String[] {
IDocument.DEFAULT_CONTENT_TYPE,
STPPartitionScanner.STP_COMMENT,
- STPPartitionScanner.STP_STRING,
- STPPartitionScanner.STP_PROBE};
+ STPPartitionScanner.STP_CONDITIONAL};
}
/* (non-Javadoc)
@@ -70,7 +69,7 @@ public class STPConfiguration extends SourceViewerConfiguration {
.setContextInformationPopupOrientation(IContentAssistant.CONTEXT_INFO_ABOVE);
assistant.setContentAssistProcessor(processor,IDocument.DEFAULT_CONTENT_TYPE);
- assistant.setContentAssistProcessor(processor,STPPartitionScanner.STP_PROBE);
+ assistant.setContentAssistProcessor(processor,STPPartitionScanner.STP_CONDITIONAL);
assistant.setInformationControlCreator(getInformationControlCreator(sourceViewer));
@@ -136,28 +135,16 @@ public class STPConfiguration extends SourceViewerConfiguration {
reconciler.setRepairer(dr, STPPartitionScanner.STP_COMMENT);
dr = new DefaultDamagerRepairer(getSTPScanner());
- reconciler.setDamager(dr, STPPartitionScanner.STP_STRING);
- reconciler.setRepairer(dr, STPPartitionScanner.STP_STRING);
-
- dr = new DefaultDamagerRepairer(getSTPScanner());
- reconciler.setDamager(dr, STPPartitionScanner.STP_KEYWORD);
- reconciler.setRepairer(dr, STPPartitionScanner.STP_KEYWORD);
-
- dr = new DefaultDamagerRepairer(getSTPScanner());
reconciler.setDamager(dr, STPPartitionScanner.STP_CONDITIONAL);
reconciler.setRepairer(dr, STPPartitionScanner.STP_CONDITIONAL);
- dr = new DefaultDamagerRepairer(getSTPScanner());
- reconciler.setDamager(dr, STPPartitionScanner.STP_PROBE);
- reconciler.setRepairer(dr, STPPartitionScanner.STP_PROBE);
-
return reconciler;
}
@Override
public IAutoEditStrategy[] getAutoEditStrategies(
ISourceViewer sourceViewer, String contentType) {
- return new IAutoEditStrategy[] {new STPAutoEditStrategy()};
+ return new IAutoEditStrategy[] {new STPAutoEditStrategy(STPPartitionScanner.STP_PARTITIONING, null)};
}
@Override
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPDefaultCodeFormatterConstants.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPDefaultCodeFormatterConstants.java
new file mode 100644
index 0000000000..830088d022
--- /dev/null
+++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPDefaultCodeFormatterConstants.java
@@ -0,0 +1,2620 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2011, 2013 QNX Software Systems and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * QNX Software Systems - Initial API and implementation
+ * Sergey Prigogin (Google)
+ * Anton Leherbauer (Wind River Systems)
+ * Red Hat Inc. - modified for use in SystemTap
+ *******************************************************************************/
+package org.eclipse.linuxtools.internal.systemtap.ui.ide.editors.stp;
+
+import java.util.Map;
+
+import org.eclipse.linuxtools.internal.systemtap.ui.ide.IDEPlugin;
+
+
+/**
+ * Constants used to set up the options of the code formatter.
+ *
+ * @since 4.0
+ * @noextend This class is not intended to be subclassed by clients.
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public class STPDefaultCodeFormatterConstants {
+
+ /**
+ * <pre>
+ * FORMATTER / Option for the language
+ * - option id: "org.eclipse.cdt.core.formatter.language"
+ * - possible values: object of class <code>ILanguage</code> or <code>null</code>
+ * - default: null
+ * </pre>
+ */
+ public static final String FORMATTER_LANGUAGE = IDEPlugin.PLUGIN_ID + ".formatter.language"; //$NON-NLS-1$
+
+ /**
+ * <pre>
+ * FORMATTER / Option for the current file
+ * - option id: "org.eclipse.cdt.core.formatter.current_file"
+ * - possible values: object of class <code>IFile</code> or <code>null</code>
+ * - default: null
+ * </pre>
+ */
+ public static final String FORMATTER_CURRENT_FILE = IDEPlugin.PLUGIN_ID + ".formatter.current_file"; //$NON-NLS-1$
+
+ /**
+ * <pre>
+ * FORMATTER / Option for the translation unit
+ * - option id: "org.eclipse.cdt.core.formatter.current_translation_unit"
+ * - possible values: object of class <code>ITranslationUnit</code> or <code>null</code>
+ * - default: null
+ * </pre>
+ */
+ public static final String FORMATTER_TRANSLATION_UNIT = IDEPlugin.PLUGIN_ID + ".formatter.current_translation_unit"; //$NON-NLS-1$
+
+ /**
+ * <pre>
+ * FORMATTER / Value to set a brace location at the end of a line.
+ * </pre>
+ * @see #FORMATTER_BRACE_POSITION_FOR_INITIALIZER_LIST
+ * @see #FORMATTER_BRACE_POSITION_FOR_BLOCK
+ * @see #FORMATTER_BRACE_POSITION_FOR_METHOD_DECLARATION
+ * @see #FORMATTER_BRACE_POSITION_FOR_SWITCH
+ * @see #FORMATTER_BRACE_POSITION_FOR_TYPE_DECLARATION
+ */
+ public static final String END_OF_LINE = "end_of_line"; //$NON-NLS-1$
+
+ /**
+ * <pre>
+ * FORMATTER / Value to set an option to false.
+ * </pre>
+ */
+ public static final String FALSE = "false"; //$NON-NLS-1$
+
+// /**
+// * <pre>
+// * FORMATTER / Option to align type members of a type declaration on column
+// * - option id: "org.eclipse.cdt.core.formatter.formatter.align_type_members_on_columns"
+// * - possible values: { TRUE, FALSE }
+// * - default: FALSE
+// * </pre>
+// * @see #TRUE
+// * @see #FALSE
+// */
+// public static final String FORMATTER_ALIGN_TYPE_MEMBERS_ON_COLUMNS = IDEPlugin.PLUGIN_ID + ".formatter.align_type_members_on_columns"; //$NON-NLS-1$
+//
+// /**
+// * <pre>
+// * FORMATTER / Option for alignment of arguments in allocation expression
+// * - option id: "org.eclipse.cdt.core.formatter.alignment_for_arguments_in_allocation_expression"
+// * - possible values: values returned by <code>createAlignmentValue(boolean, int, int)</code> call
+// * - default: createAlignmentValue(false, WRAP_COMPACT, INDENT_DEFAULT)
+// * </pre>
+// * @see #createAlignmentValue(boolean, int, int)
+// */
+// public static final String FORMATTER_ALIGNMENT_FOR_ARGUMENTS_IN_ALLOCATION_EXPRESSION = IDEPlugin.PLUGIN_ID + ".formatter.alignment_for_arguments_in_allocation_expression"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option for alignment of arguments in method invocation
+ * - option id: "org.eclipse.cdt.core.formatter.alignment_for_arguments_in_method_invocation"
+ * - possible values: values returned by <code>createAlignmentValue(boolean, int, int)</code> call
+ * - default: createAlignmentValue(false, WRAP_COMPACT, INDENT_DEFAULT)
+ * </pre>
+ * @see #createAlignmentValue(boolean, int, int)
+ */
+ public static final String FORMATTER_ALIGNMENT_FOR_ARGUMENTS_IN_METHOD_INVOCATION = IDEPlugin.PLUGIN_ID + ".formatter.alignment_for_arguments_in_method_invocation"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option for alignment of assignment
+ * - option id: "org.eclipse.cdt.core.formatter.alignment_for_assignment"
+ * - possible values: values returned by <code>createAlignmentValue(boolean, int, int)</code> call
+ * - default: createAlignmentValue(false, WRAP_COMPACT, INDENT_DEFAULT)
+ * </pre>
+ * @see #createAlignmentValue(boolean, int, int)
+ * @since 5.3
+ */
+ public static final String FORMATTER_ALIGNMENT_FOR_ASSIGNMENT = IDEPlugin.PLUGIN_ID + ".formatter.alignment_for_assignment"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option for alignment of binary expression
+ * - option id: "org.eclipse.cdt.core.formatter.alignment_for_binary_expression"
+ * - possible values: values returned by <code>createAlignmentValue(boolean, int, int)</code> call
+ * - default: createAlignmentValue(false, WRAP_COMPACT, INDENT_DEFAULT)
+ * </pre>
+ * @see #createAlignmentValue(boolean, int, int)
+ * @since 5.3
+ */
+ public static final String FORMATTER_ALIGNMENT_FOR_BINARY_EXPRESSION = IDEPlugin.PLUGIN_ID + ".formatter.alignment_for_binary_expression"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option for alignment of compact if
+ * - option id: "org.eclipse.cdt.core.formatter.alignment_for_compact_if"
+ * - possible values: values returned by <code>createAlignmentValue(boolean, int, int)</code> call
+ * - default: createAlignmentValue(false, WRAP_ONE_PER_LINE, INDENT_BY_ONE)
+ * </pre>
+ * @see #createAlignmentValue(boolean, int, int)
+ */
+ public static final String FORMATTER_ALIGNMENT_FOR_COMPACT_IF = IDEPlugin.PLUGIN_ID + ".formatter.alignment_for_compact_if"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option for alignment of conditional expression
+ * - option id: "org.eclipse.cdt.core.formatter.alignment_for_conditional_expression"
+ * - possible values: values returned by <code>createAlignmentValue(boolean, int, int)</code> call
+ * - default: createAlignmentValue(false, WRAP_COMPACT_FIRST_BREAK, INDENT_ON_COLUMN)
+ * </pre>
+ * @see #createAlignmentValue(boolean, int, int)
+ */
+ public static final String FORMATTER_ALIGNMENT_FOR_CONDITIONAL_EXPRESSION = IDEPlugin.PLUGIN_ID + ".formatter.alignment_for_conditional_expression"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option for alignment of a chain of conditional expressions.
+ * - option id: "org.eclipse.cdt.core.formatter.alignment_for_conditional_expression_chain"
+ * - possible values: values returned by <code>createAlignmentValue(boolean, int, int)</code> call
+ * - default: createAlignmentValue(false, WRAP_COMPACT, INDENT_ON_COLUMN)
+ * </pre>
+ * @see #createAlignmentValue(boolean, int, int)
+ * @since 5.3
+ */
+ public static final String FORMATTER_ALIGNMENT_FOR_CONDITIONAL_EXPRESSION_CHAIN = IDEPlugin.PLUGIN_ID + ".formatter.alignment_for_conditional_expression_chain"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option for alignment of a declarator list
+ * - option id: "org.eclipse.cdt.core.formatter.alignment_for_declarator_list"
+ * - possible values: values returned by <code>createAlignmentValue(boolean, int, int)</code> call
+ * - default: createAlignmentValue(false, WRAP_COMPACT, INDENT_DEFAULT)
+ * </pre>
+ * @see #createAlignmentValue(boolean, int, int)
+ */
+ public static final String FORMATTER_ALIGNMENT_FOR_DECLARATOR_LIST = IDEPlugin.PLUGIN_ID + ".formatter.alignment_for_declarator_list"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option for alignment of a enumerator list
+ * - option id: "org.eclipse.cdt.core.formatter.alignment_for_enumerator_list"
+ * - possible values: values returned by <code>createAlignmentValue(boolean, int, int)</code> call
+ * - default: createAlignmentValue(false, WRAP_ONE_PER_LINE, INDENT_DEFAULT)
+ * </pre>
+ * @see #createAlignmentValue(boolean, int, int)
+ */
+ public static final String FORMATTER_ALIGNMENT_FOR_ENUMERATOR_LIST = IDEPlugin.PLUGIN_ID + ".formatter.alignment_for_enumerator_list"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option for alignment of a expression list (except arguments in a method invocation)
+ * - option id: "org.eclipse.cdt.core.formatter.alignment_for_expression_list"
+ * - possible values: values returned by <code>createAlignmentValue(boolean, int, int)</code> call
+ * - default: createAlignmentValue(false, WRAP_COMPACT, INDENT_DEFAULT)
+ * </pre>
+ * @see #createAlignmentValue(boolean, int, int)
+ */
+ public static final String FORMATTER_ALIGNMENT_FOR_EXPRESSION_LIST = IDEPlugin.PLUGIN_ID + ".formatter.alignment_for_expression_list"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option for alignment of expressions in initializer list
+ * - option id: "org.eclipse.cdt.core.formatter.alignment_for_expressions_in_array_initializer"
+ * - possible values: values returned by <code>createAlignmentValue(boolean, int, int)</code> call
+ * - default: createAlignmentValue(false, WRAP_COMPACT, INDENT_DEFAULT)
+ * </pre>
+ * @see #createAlignmentValue(boolean, int, int)
+ */
+ public static final String FORMATTER_ALIGNMENT_FOR_EXPRESSIONS_IN_INITIALIZER_LIST = IDEPlugin.PLUGIN_ID + ".formatter.alignment_for_expressions_in_array_initializer"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option for alignment of member access
+ * - option id: "org.eclipse.cdt.core.formatter.alignment_for_member_access"
+ * - possible values: values returned by <code>createAlignmentValue(boolean, int, int)</code> call
+ * - default: createAlignmentValue(false, M_NO_ALIGNMENT, INDENT_DEFAULT)
+ * </pre>
+ * @see #createAlignmentValue(boolean, int, int)
+ * @since 5.3
+ */
+ public static final String FORMATTER_ALIGNMENT_FOR_MEMBER_ACCESS = IDEPlugin.PLUGIN_ID + ".formatter.alignment_for_member_access"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option for alignment of stream output expression consisting of a chain of
+ * overloaded &lt;&lt; operators.
+ * - option id: "org.eclipse.cdt.core.formatter.alignment_for_overloaded_left_shift_chainn"
+ * - possible values: values returned by <code>createAlignmentValue(boolean, int, int)</code> call
+ * - default: createAlignmentValue(false, WRAP_COMPACT, INDENT_DEFAULT)
+ * </pre>
+ * @see #createAlignmentValue(boolean, int, int)
+ * @since 5.3
+ */
+ public static final String FORMATTER_ALIGNMENT_FOR_OVERLOADED_LEFT_SHIFT_CHAIN = IDEPlugin.PLUGIN_ID + ".formatter.alignment_for_overloaded_left_shift_chain"; //$NON-NLS-1$;
+ /**
+ * <pre>
+ * FORMATTER / Option for alignment of parameters in method declaration
+ * - option id: "org.eclipse.cdt.core.formatter.alignment_for_parameters_in_method_declaration"
+ * - possible values: values returned by <code>createAlignmentValue(boolean, int, int)</code> call
+ * - default: createAlignmentValue(false, WRAP_COMPACT, INDENT_DEFAULT)
+ * </pre>
+ * @see #createAlignmentValue(boolean, int, int)
+ */
+ public static final String FORMATTER_ALIGNMENT_FOR_PARAMETERS_IN_METHOD_DECLARATION = IDEPlugin.PLUGIN_ID + ".formatter.alignment_for_parameters_in_method_declaration"; //$NON-NLS-1$
+// /**
+// * <pre>
+// * FORMATTER / Option for alignment of selector in method invocation
+// * - option id: "org.eclipse.cdt.core.formatter.alignment_for_selector_in_method_invocation"
+// * - possible values: values returned by <code>createAlignmentValue(boolean, int, int)</code> call
+// * - default: createAlignmentValue(false, WRAP_COMPACT, INDENT_DEFAULT)
+// * </pre>
+// * @see #createAlignmentValue(boolean, int, int)
+// */
+// public static final String FORMATTER_ALIGNMENT_FOR_SELECTOR_IN_METHOD_INVOCATION = IDEPlugin.PLUGIN_ID + ".formatter.alignment_for_selector_in_method_invocation"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option for alignment of base-clause in type declaration
+ * - option id: "org.eclipse.cdt.core.formatter.alignment_for_base_clause_in_type_declaration"
+ * - possible values: values returned by <code>createAlignmentValue(boolean, int, int)</code> call
+ * - default: createAlignmentValue(false, WRAP_NEXT_SHIFTED, INDENT_DEFAULT)
+ * </pre>
+ * @see #createAlignmentValue(boolean, int, int)
+ */
+ public static final String FORMATTER_ALIGNMENT_FOR_BASE_CLAUSE_IN_TYPE_DECLARATION = IDEPlugin.PLUGIN_ID + ".formatter.alignment_for_base_clause_in_type_declaration"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option for alignment of constructor initializer list
+ * - option id: "org.eclipse.cdt.core.formatter.alignment_for_constructor_initializer_list"
+ * - possible values: values returned by <code>createAlignmentValue(boolean, int, int)</code> call
+ * - default: createAlignmentValue(false, WRAP_COMPACT, INDENT_DEFAULT)
+ * </pre>
+ * @see #createAlignmentValue(boolean, int, int)
+ * @since 5.3
+ */
+ public static final String FORMATTER_ALIGNMENT_FOR_CONSTRUCTOR_INITIALIZER_LIST = IDEPlugin.PLUGIN_ID + ".formatter.alignment_for_constructor_initializer_list"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option for alignment of throws clause in method declaration
+ * - option id: "org.eclipse.cdt.core.formatter.alignment_for_throws_clause_in_method_declaration"
+ * - possible values: values returned by <code>createAlignmentValue(boolean, int, int)</code> call
+ * - default: createAlignmentValue(false, WRAP_COMPACT, INDENT_DEFAULT)
+ * </pre>
+ * @see #createAlignmentValue(boolean, int, int)
+ */
+ public static final String FORMATTER_ALIGNMENT_FOR_THROWS_CLAUSE_IN_METHOD_DECLARATION = IDEPlugin.PLUGIN_ID + ".formatter.alignment_for_throws_clause_in_method_declaration"; //$NON-NLS-1$
+// /**
+// * <pre>
+// * FORMATTER / Option to add blank lines after #include directive
+// * - option id: "org.eclipse.cdt.core.formatter.blank_lines_after_includes"
+// * - possible values: "&lt;n&gt;", where n is zero or a positive integer
+// * - default: "0"
+// * </pre>
+// */
+// public static final String FORMATTER_BLANK_LINES_AFTER_INCLUDES = IDEPlugin.PLUGIN_ID + ".formatter.blank_lines_after_includes"; //$NON-NLS-1$
+// /**
+// * <pre>
+// * FORMATTER / Option to add blank lines at the beginning of the method body
+// * - option id: "org.eclipse.cdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body"
+// * - possible values: "&lt;n&gt;", where n is zero or a positive integer
+// * - default: "0"
+// * </pre>
+// */
+// public static final String FORMATTER_BLANK_LINES_AT_BEGINNING_OF_METHOD_BODY = IDEPlugin.PLUGIN_ID + ".formatter.number_of_blank_lines_at_beginning_of_method_body"; //$NON-NLS-1$
+// /**
+// * <pre>
+// * FORMATTER / Option to add blank lines before a field declaration
+// * - option id: "org.eclipse.cdt.core.formatter.blank_lines_before_field"
+// * - possible values: "&lt;n&gt;", where n is zero or a positive integer
+// * - default: "0"
+// * </pre>
+// */
+// public static final String FORMATTER_BLANK_LINES_BEFORE_FIELD = IDEPlugin.PLUGIN_ID + ".formatter.blank_lines_before_field"; //$NON-NLS-1$
+// /**
+// * <pre>
+// * FORMATTER / Option to add blank lines before the first class body declaration
+// * - option id: "org.eclipse.cdt.core.formatter.blank_lines_before_first_class_body_declaration"
+// * - possible values: "&lt;n&gt;", where n is zero or a positive integer
+// * - default: "0"
+// * </pre>
+// */
+// public static final String FORMATTER_BLANK_LINES_BEFORE_FIRST_CLASS_BODY_DECLARATION = IDEPlugin.PLUGIN_ID + ".formatter.blank_lines_before_first_class_body_declaration"; //$NON-NLS-1$
+// /**
+// * <pre>
+// * FORMATTER / Option to add blank lines before #include directive
+// * - option id: "org.eclipse.cdt.core.formatter.blank_lines_before_includes"
+// * - possible values: "&lt;n&gt;", where n is zero or a positive integer
+// * - default: "0"
+// * </pre>
+// */
+// public static final String FORMATTER_BLANK_LINES_BEFORE_INCLUDES = IDEPlugin.PLUGIN_ID + ".formatter.blank_lines_before_includes"; //$NON-NLS-1$
+// /**
+// * <pre>
+// * FORMATTER / Option to add blank lines before a member type declaration
+// * - option id: "org.eclipse.cdt.core.formatter.blank_lines_before_member_type"
+// * - possible values: "&lt;n&gt;", where n is zero or a positive integer
+// * - default: "0"
+// * </pre>
+// */
+// public static final String FORMATTER_BLANK_LINES_BEFORE_MEMBER_TYPE = IDEPlugin.PLUGIN_ID + ".formatter.blank_lines_before_member_type"; //$NON-NLS-1$
+// /**
+// * <pre>
+// * FORMATTER / Option to add blank lines before a method declaration
+// * - option id: "org.eclipse.cdt.core.formatter.blank_lines_before_method"
+// * - possible values: "&lt;n&gt;", where n is zero or a positive integer
+// * - default: "0"
+// * </pre>
+// */
+// public static final String FORMATTER_BLANK_LINES_BEFORE_METHOD = IDEPlugin.PLUGIN_ID + ".formatter.blank_lines_before_method"; //$NON-NLS-1$
+// /**
+// * <pre>
+// * FORMATTER / Option to add blank lines before a new chunk
+// * - option id: "org.eclipse.cdt.core.formatter.blank_lines_before_new_chunk"
+// * - possible values: "&lt;n&gt;", where n is zero or a positive integer
+// * - default: "0"
+// * </pre>
+// */
+// public static final String FORMATTER_BLANK_LINES_BEFORE_NEW_CHUNK = IDEPlugin.PLUGIN_ID + ".formatter.blank_lines_before_new_chunk"; //$NON-NLS-1$
+// /**
+// * <pre>
+// * FORMATTER / Option to add blank lines between type declarations
+// * - option id: "org.eclipse.cdt.core.formatter.blank_lines_between_type_declarations"
+// * - possible values: "&lt;n&gt;", where n is zero or a positive integer
+// * - default: "0"
+// * </pre>
+// */
+// public static final String FORMATTER_BLANK_LINES_BETWEEN_TYPE_DECLARATIONS = IDEPlugin.PLUGIN_ID + ".formatter.blank_lines_between_type_declarations"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to position the braces of initializer list
+ * - option id: "org.eclipse.cdt.core.formatter.brace_position_for_array_initializer"
+ * - possible values: { END_OF_LINE, NEXT_LINE, NEXT_LINE_SHIFTED, NEXT_LINE_ON_WRAP }
+ * - default: END_OF_LINE
+ * </pre>
+ * @see #END_OF_LINE
+ * @see #NEXT_LINE
+ * @see #NEXT_LINE_SHIFTED
+ * @see #NEXT_LINE_ON_WRAP
+ */
+ public static final String FORMATTER_BRACE_POSITION_FOR_INITIALIZER_LIST = IDEPlugin.PLUGIN_ID + ".formatter.brace_position_for_array_initializer"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to position the braces of a block
+ * - option id: "org.eclipse.cdt.core.formatter.brace_position_for_block"
+ * - possible values: { END_OF_LINE, NEXT_LINE, NEXT_LINE_SHIFTED, NEXT_LINE_ON_WRAP }
+ * - default: END_OF_LINE
+ * </pre>
+ * @see #END_OF_LINE
+ * @see #NEXT_LINE
+ * @see #NEXT_LINE_SHIFTED
+ * @see #NEXT_LINE_ON_WRAP
+ */
+ public static final String FORMATTER_BRACE_POSITION_FOR_BLOCK = IDEPlugin.PLUGIN_ID + ".formatter.brace_position_for_block"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to position the braces of a block in a case statement when the block is the first statement following
+ * the case
+ * - option id: "org.eclipse.cdt.core.formatter.brace_position_for_block_in_case"
+ * - possible values: { END_OF_LINE, NEXT_LINE, NEXT_LINE_SHIFTED, NEXT_LINE_ON_WRAP }
+ * - default: END_OF_LINE
+ * </pre>
+ * @see #END_OF_LINE
+ * @see #NEXT_LINE
+ * @see #NEXT_LINE_SHIFTED
+ * @see #NEXT_LINE_ON_WRAP
+ */
+ public static final String FORMATTER_BRACE_POSITION_FOR_BLOCK_IN_CASE = IDEPlugin.PLUGIN_ID + ".formatter.brace_position_for_block_in_case"; //$NON-NLS-1$
+// /**
+// * <pre>
+// * FORMATTER / Option to position the braces of an enum declaration
+// * - option id: "org.eclipse.cdt.core.formatter.brace_position_for_enum_declaration"
+// * - possible values: { END_OF_LINE, NEXT_LINE, NEXT_LINE_SHIFTED, NEXT_LINE_ON_WRAP }
+// * - default: END_OF_LINE
+// * </pre>
+// * @see #END_OF_LINE
+// * @see #NEXT_LINE
+// * @see #NEXT_LINE_SHIFTED
+// * @see #NEXT_LINE_ON_WRAP
+// */
+// public static final String FORMATTER_BRACE_POSITION_FOR_ENUM_DECLARATION = IDEPlugin.PLUGIN_ID + ".formatter.brace_position_for_enum_declaration"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to position the braces of a method declaration
+ * - option id: "org.eclipse.cdt.core.formatter.brace_position_for_method_declaration"
+ * - possible values: { END_OF_LINE, NEXT_LINE, NEXT_LINE_SHIFTED, NEXT_LINE_ON_WRAP }
+ * - default: END_OF_LINE
+ * </pre>
+ * @see #END_OF_LINE
+ * @see #NEXT_LINE
+ * @see #NEXT_LINE_SHIFTED
+ * @see #NEXT_LINE_ON_WRAP
+ */
+ public static final String FORMATTER_BRACE_POSITION_FOR_METHOD_DECLARATION = IDEPlugin.PLUGIN_ID + ".formatter.brace_position_for_method_declaration"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to position the braces of a switch statement
+ * - option id: "org.eclipse.cdt.core.formatter.brace_position_for_switch"
+ * - possible values: { END_OF_LINE, NEXT_LINE, NEXT_LINE_SHIFTED, NEXT_LINE_ON_WRAP }
+ * - default: END_OF_LINE
+ * </pre>
+ * @see #END_OF_LINE
+ * @see #NEXT_LINE
+ * @see #NEXT_LINE_SHIFTED
+ * @see #NEXT_LINE_ON_WRAP
+ */
+ public static final String FORMATTER_BRACE_POSITION_FOR_SWITCH = IDEPlugin.PLUGIN_ID + ".formatter.brace_position_for_switch"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to position the braces of a type declaration
+ * - option id: "org.eclipse.cdt.core.formatter.brace_position_for_type_declaration"
+ * - possible values: { END_OF_LINE, NEXT_LINE, NEXT_LINE_SHIFTED, NEXT_LINE_ON_WRAP }
+ * - default: END_OF_LINE
+ * </pre>
+ * @see #END_OF_LINE
+ * @see #NEXT_LINE
+ * @see #NEXT_LINE_SHIFTED
+ * @see #NEXT_LINE_ON_WRAP
+ */
+ public static final String FORMATTER_BRACE_POSITION_FOR_TYPE_DECLARATION = IDEPlugin.PLUGIN_ID + ".formatter.brace_position_for_type_declaration"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to position the braces of a namespace declaration
+ * - option id: "org.eclipse.cdt.core.formatter.brace_position_for_namespace_declaration"
+ * - possible values: { END_OF_LINE, NEXT_LINE, NEXT_LINE_SHIFTED, NEXT_LINE_ON_WRAP }
+ * - default: END_OF_LINE
+ * </pre>
+ * @see #END_OF_LINE
+ * @see #NEXT_LINE
+ * @see #NEXT_LINE_SHIFTED
+ * @see #NEXT_LINE_ON_WRAP
+ */
+ public static final String FORMATTER_BRACE_POSITION_FOR_NAMESPACE_DECLARATION = IDEPlugin.PLUGIN_ID + ".formatter.brace_position_for_namespace_declaration"; //$NON-NLS-1$
+
+// /**
+// * <pre>
+// * FORMATTER / Option to control whether blank lines are cleared inside comments
+// * - option id: "org.eclipse.cdt.core.formatter.comment.clear_blank_lines"
+// * - possible values: { TRUE, FALSE }
+// * - default: FALSE
+// * </pre>
+// * @see #TRUE
+// * @see #FALSE
+// */
+// public final static String FORMATTER_COMMENT_CLEAR_BLANK_LINES = IDEPlugin.PLUGIN_ID + ".formatter.comment.clear_blank_lines"; //$NON-NLS-1$
+//
+// /**
+// * <pre>
+// * FORMATTER / Option to control whether comments are formatted
+// * - option id: "org.eclipse.cdt.core.formatter.comment.format_comments"
+// * - possible values: { TRUE, FALSE }
+// * - default: TRUE
+// * </pre>
+// * @see #TRUE
+// * @see #FALSE
+// */
+// public final static String FORMATTER_COMMENT_FORMAT = IDEPlugin.PLUGIN_ID + ".formatter.comment.format_comments"; //$NON-NLS-1$
+//
+// /**
+// * <pre>
+// * FORMATTER / Option to control whether the header comment of a C/C++ source file is formatted
+// * - option id: "org.eclipse.cdt.core.formatter.comment.format_header"
+// * - possible values: { TRUE, FALSE }
+// * - default: FALSE
+// * </pre>
+// * @see #TRUE
+// * @see #FALSE
+// */
+// public final static String FORMATTER_COMMENT_FORMAT_HEADER = IDEPlugin.PLUGIN_ID + ".formatter.comment.format_header"; //$NON-NLS-1$
+//
+// /**
+// * <pre>
+// * FORMATTER / Option to control whether code snippets are formatted in comments
+// * - option id: "org.eclipse.cdt.core.formatter.comment.format_source_code"
+// * - possible values: { TRUE, FALSE }
+// * - default: TRUE
+// * </pre>
+// * @see #TRUE
+// * @see #FALSE
+// */
+// public final static String FORMATTER_COMMENT_FORMAT_SOURCE = IDEPlugin.PLUGIN_ID + ".formatter.comment.format_source_code"; //$NON-NLS-1$
+//
+// /**
+// * <pre>
+// * FORMATTER / Option to specify the line length for comments.
+// * - option id: "org.eclipse.cdt.core.formatter.comment.line_length"
+// * - possible values: "&lt;n&gt;", where n is zero or a positive integer
+// * - default: "80"
+// * </pre>
+// */
+// public final static String FORMATTER_COMMENT_LINE_LENGTH = IDEPlugin.PLUGIN_ID + ".formatter.comment.line_length"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to specify the minimum distance between code and line comment.
+ * - option id: "org.eclipse.cdt.core.formatter.comment.min_distance_between_code_and_line_comment"
+ * - possible values: "&lt;n&gt;", where n is zero or a positive integer
+ * - default: "1"
+ * </pre>
+ * @since 5.3
+ */
+ public final static String FORMATTER_COMMENT_MIN_DISTANCE_BETWEEN_CODE_AND_LINE_COMMENT = IDEPlugin.PLUGIN_ID + ".formatter.comment.min_distance_between_code_and_line_comment"; //$NON-NLS-1$
+
+ /**
+ * <pre>
+ * FORMATTER / Option to control whether the white space between code and line comments should be preserved or replaced with a single space
+ * - option id: "org.eclipse.cdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments"
+ * - possible values: { TRUE, FALSE }
+ * - default: FALSE
+ * </pre>
+ * @see #TRUE
+ * @see #FALSE
+ * @since 5.3
+ */
+ public final static String FORMATTER_COMMENT_PRESERVE_WHITE_SPACE_BETWEEN_CODE_AND_LINE_COMMENT = IDEPlugin.PLUGIN_ID + ".formatter.comment.preserve_white_space_between_code_and_line_comments"; //$NON-NLS-1$
+
+ /**
+ * <pre>
+ * FORMATTER / Option to control whether comments starting from the beginning of line should stay that way and never be indented.
+ * - option id: "org.eclipse.cdt.core.formatter.comment.never_indent_line_comments_on_first_column"
+ * - possible values: { TRUE, FALSE }
+ * - default: TRUE
+ * </pre>
+ * @see #TRUE
+ * @see #FALSE
+ * @since 5.4
+ */
+ public final static String FORMATTER_COMMENT_NEVER_INDENT_LINE_COMMENTS_ON_FIRST_COLUMN = IDEPlugin.PLUGIN_ID + ".formatter.comment.never_indent_line_comments_on_first_column"; //$NON-NLS-1$
+
+ /**
+ * <pre>
+ * FORMATTER / Option to compact else/if
+ * - option id: "org.eclipse.cdt.core.formatter.compact_else_if"
+ * - possible values: { TRUE, FALSE }
+ * - default: TRUE
+ * </pre>
+ * @see #TRUE
+ * @see #FALSE
+ */
+ public static final String FORMATTER_COMPACT_ELSE_IF = IDEPlugin.PLUGIN_ID + ".formatter.compact_else_if"; //$NON-NLS-1$
+
+ /**
+ * <pre>
+ * FORMATTER / Option to set the continuation indentation
+ * - option id: "org.eclipse.cdt.core.formatter.continuation_indentation"
+ * - possible values: "&lt;n&gt;", where n is zero or a positive integer
+ * - default: "2"
+ * </pre>
+ */
+ public static final String FORMATTER_CONTINUATION_INDENTATION = IDEPlugin.PLUGIN_ID + ".formatter.continuation_indentation"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to set the continuation indentation inside initializer list
+ * - option id: "org.eclipse.cdt.core.formatter.continuation_indentation_for_array_initializer"
+ * - possible values: "&lt;n&gt;", where n is zero or a positive integer
+ * - default: "2"
+ * </pre>
+ */
+ public static final String FORMATTER_CONTINUATION_INDENTATION_FOR_INITIALIZER_LIST = IDEPlugin.PLUGIN_ID + ".formatter.continuation_indentation_for_array_initializer"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to indent 'public:', 'protected:', 'private:' access specifiers relative to class declaration.
+ * - option id: "org.eclipse.cdt.core.formatter.indent_access_specifier_compare_to_type_header"
+ * - possible values: { TRUE, FALSE }
+ * - default: FALSE
+ * </pre>
+ * @see #TRUE
+ * @see #FALSE
+ */
+ public static final String FORMATTER_INDENT_ACCESS_SPECIFIER_COMPARE_TO_TYPE_HEADER = IDEPlugin.PLUGIN_ID + ".formatter.indent_access_specifier_compare_to_type_header"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Number of extra spaces in front of 'public:', 'protected:', 'private:' access specifiers.
+ * Enables fractional indent of access specifiers. Does not affect indentation of body declarations.
+ * - option id: "org.eclipse.cdt.core.formatter.indent_access_specifier_extra_spaces"
+ * - possible values: "&lt;n&gt;", where n is zero or a positive integer
+ * - default: "0"
+ * </pre>
+ * @since 5.2
+ */
+ public static final String FORMATTER_INDENT_ACCESS_SPECIFIER_EXTRA_SPACES = IDEPlugin.PLUGIN_ID + ".formatter.indent_access_specifier_extra_spaces"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to indent body declarations relative to access specifiers (visibility labels)
+ * - option id: "org.eclipse.cdt.core.formatter.indent_body_declarations_compare_to_access_specifier"
+ * - possible values: { TRUE, FALSE }
+ * - default: TRUE
+ * </pre>
+ * @see #TRUE
+ * @see #FALSE
+ */
+ public static final String FORMATTER_INDENT_BODY_DECLARATIONS_COMPARE_TO_ACCESS_SPECIFIER = IDEPlugin.PLUGIN_ID + ".formatter.indent_body_declarations_compare_to_access_specifier"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to indent template declaration compare to template header
+ * - option id: "org.eclipse.cdt.core.formatter.indent_declaration_compare_to_template_header"
+ * - possible values: { TRUE, FALSE }
+ * - default: FALSE
+ * </pre>
+ * @see #TRUE
+ * @see #FALSE
+ */
+ public static final String FORMATTER_INDENT_DECLARATION_COMPARE_TO_TEMPLATE_HEADER = IDEPlugin.PLUGIN_ID + ".formatter.indent_declaration_compare_to_template_header"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to indent body declarations compare to its enclosing namespace header
+ * - option id: "org.eclipse.cdt.core.formatter.indent_body_declarations_compare_to_namespace_header"
+ * - possible values: { TRUE, FALSE }
+ * - default: TRUE
+ * </pre>
+ * @see #TRUE
+ * @see #FALSE
+ */
+ public static final String FORMATTER_INDENT_BODY_DECLARATIONS_COMPARE_TO_NAMESPACE_HEADER = IDEPlugin.PLUGIN_ID + ".formatter.indent_body_declarations_compare_to_namespace_header"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to indent breaks compare to cases
+ * - option id: "org.eclipse.cdt.core.formatter.indent_breaks_compare_to_cases"
+ * - possible values: { TRUE, FALSE }
+ * - default: TRUE
+ * </pre>
+ * @see #TRUE
+ * @see #FALSE
+ */
+ public static final String FORMATTER_INDENT_BREAKS_COMPARE_TO_CASES = IDEPlugin.PLUGIN_ID + ".formatter.indent_breaks_compare_to_cases"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to indent empty lines
+ * - option id: "org.eclipse.cdt.core.formatter.indent_empty_lines"
+ * - possible values: { TRUE, FALSE }
+ * - default: FALSE
+ * </pre>
+ * @see #TRUE
+ * @see #FALSE
+ */
+ public static final String FORMATTER_INDENT_EMPTY_LINES = IDEPlugin.PLUGIN_ID + ".formatter.indent_empty_lines"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to indent inside line comments at column 0
+ * - option id: "org.eclipse.cdt.core.formatter.indent_inside_line_comments"
+ * - possible values: { TRUE, FALSE }
+ * - default: FALSE
+ * </pre>
+ * @see #TRUE
+ * @see #FALSE
+ */
+ public static final String FORMATTER_INDENT_INSIDE_LINE_COMMENTS = IDEPlugin.PLUGIN_ID + ".formatter.indent_inside_line_comments"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to indent statements inside a block
+ * - option id: "org.eclipse.cdt.core.formatter.indent_statements_compare_to_block"
+ * - possible values: { TRUE, FALSE }
+ * - default: TRUE
+ * </pre>
+ * @see #TRUE
+ * @see #FALSE
+ */
+ public static final String FORMATTER_INDENT_STATEMENTS_COMPARE_TO_BLOCK = IDEPlugin.PLUGIN_ID + ".formatter.indent_statements_compare_to_block"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to indent statements inside the body of a method or a constructor
+ * - option id: "org.eclipse.cdt.core.formatter.indent_statements_compare_to_body"
+ * - possible values: { TRUE, FALSE }
+ * - default: TRUE
+ * </pre>
+ * @see #TRUE
+ * @see #FALSE
+ */
+ public static final String FORMATTER_INDENT_STATEMENTS_COMPARE_TO_BODY = IDEPlugin.PLUGIN_ID + ".formatter.indent_statements_compare_to_body"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to indent switch statements compare to cases
+ * - option id: "org.eclipse.cdt.core.formatter.indent_switchstatements_compare_to_cases"
+ * - possible values: { TRUE, FALSE }
+ * - default: TRUE
+ * </pre>
+ * @see #TRUE
+ * @see #FALSE
+ */
+ public static final String FORMATTER_INDENT_SWITCHSTATEMENTS_COMPARE_TO_CASES = IDEPlugin.PLUGIN_ID + ".formatter.indent_switchstatements_compare_to_cases"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to indent switch statements compare to switch
+ * - option id: "org.eclipse.cdt.core.formatter.indent_switchstatements_compare_to_switch"
+ * - possible values: { TRUE, FALSE }
+ * - default: TRUE
+ * </pre>
+ * @see #TRUE
+ * @see #FALSE
+ */
+ public static final String FORMATTER_INDENT_SWITCHSTATEMENTS_COMPARE_TO_SWITCH = IDEPlugin.PLUGIN_ID + ".formatter.indent_switchstatements_compare_to_switch"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to specify the equivalent number of spaces that represents one indentation
+ * - option id: "org.eclipse.cdt.core.formatter.indentation.size"
+ * - possible values: "&lt;n&gt;", where n is zero or a positive integer
+ * - default: "4"
+ * </pre>
+ * <p>This option is used only if the tab char is set to MIXED.
+ * </p>
+ * @see #FORMATTER_TAB_CHAR
+ */
+ public static final String FORMATTER_INDENTATION_SIZE = IDEPlugin.PLUGIN_ID + ".formatter.indentation.size"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to insert a new line after the opening brace in an initializer list
+ * - option id: "org.eclipse.cdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer"
+ * - possible values: { INSERT, DO_NOT_INSERT }
+ * - default: DO_NOT_INSERT
+ * </pre>
+ * @see IDEPlugin#INSERT
+ * @see IDEPlugin#DO_NOT_INSERT
+ */
+ public static final String FORMATTER_INSERT_NEW_LINE_AFTER_OPENING_BRACE_IN_INITIALIZER_LIST = IDEPlugin.PLUGIN_ID + ".formatter.insert_new_line_after_opening_brace_in_array_initializer";//$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to insert a new line after template declaration
+ * - option id: "org.eclipse.cdt.core.formatter.insert_new_line_after_template_declaration"
+ * - possible values: { INSERT, DO_NOT_INSERT }
+ * - default: INSERT
+ * </pre>
+ * @see IDEPlugin#INSERT
+ * @see IDEPlugin#DO_NOT_INSERT
+ */
+ public static final String FORMATTER_INSERT_NEW_LINE_AFTER_TEMPLATE_DECLARATION = IDEPlugin.PLUGIN_ID + ".formatter.insert_new_line_after_template_declaration";//$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to insert a new line at the end of the current file if missing
+ * - option id: "org.eclipse.cdt.core.formatter.insert_new_line_at_end_of_file_if_missing"
+ * - possible values: { INSERT, DO_NOT_INSERT }
+ * - default: DO_NOT_INSERT
+ * </pre>
+ * @see IDEPlugin#INSERT
+ * @see IDEPlugin#DO_NOT_INSERT
+ */
+ public static final String FORMATTER_INSERT_NEW_LINE_AT_END_OF_FILE_IF_MISSING = IDEPlugin.PLUGIN_ID + ".formatter.insert_new_line_at_end_of_file_if_missing";//$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to insert a new line before the catch keyword in try statement
+ * - option id: "org.eclipse.cdt.core.formatter.insert_new_line_before_catch_in_try_statement"
+ * - possible values: { INSERT, DO_NOT_INSERT }
+ * - default: DO_NOT_INSERT
+ * </pre>
+ * @see IDEPlugin#INSERT
+ * @see IDEPlugin#DO_NOT_INSERT
+ */
+ public static final String FORMATTER_INSERT_NEW_LINE_BEFORE_CATCH_IN_TRY_STATEMENT = IDEPlugin.PLUGIN_ID + ".formatter.insert_new_line_before_catch_in_try_statement"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to insert a new line before the closing brace in an initializer list
+ * - option id: "org.eclipse.cdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer"
+ * - possible values: { INSERT, DO_NOT_INSERT }
+ * - default: DO_NOT_INSERT
+ * </pre>
+ * @see IDEPlugin#INSERT
+ * @see IDEPlugin#DO_NOT_INSERT
+ */
+ public static final String FORMATTER_INSERT_NEW_LINE_BEFORE_CLOSING_BRACE_IN_INITIALIZER_LIST = IDEPlugin.PLUGIN_ID + ".formatter.insert_new_line_before_closing_brace_in_array_initializer";//$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to insert a new line before colon in constructor initializer list.
+ * - option id: "org.eclipse.cdt.core.formatter.formatter.insert_new_line_before_colon_in_constructor_initializer_list"
+ * - possible values: { DO_NOT_INSERT, INSERT }
+ * - default: DO_NOT_INSERT
+ * </pre>
+ * @see IDEPlugin#INSERT
+ * @see IDEPlugin#DO_NOT_INSERT
+ * @since 5.3
+ */
+ public static final String FORMATTER_INSERT_NEW_LINE_BEFORE_COLON_IN_CONSTRUCTOR_INITIALIZER_LIST = IDEPlugin.PLUGIN_ID + ".formatter.insert_new_line_before_colon_in_constructor_initializer_list"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to insert a new line before the else keyword in if statement
+ * - option id: "org.eclipse.cdt.core.formatter.insert_new_line_before_else_in_if_statement"
+ * - possible values: { INSERT, DO_NOT_INSERT }
+ * - default: DO_NOT_INSERT
+ * </pre>
+ * @see IDEPlugin#INSERT
+ * @see IDEPlugin#DO_NOT_INSERT
+ */
+ public static final String FORMATTER_INSERT_NEW_LINE_BEFORE_ELSE_IN_IF_STATEMENT = IDEPlugin.PLUGIN_ID + ".formatter.insert_new_line_before_else_in_if_statement"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to insert a new line before while in do statement
+ * - option id: "org.eclipse.cdt.core.formatter.insert_new_line_before_while_in_do_statement"
+ * - possible values: { INSERT, DO_NOT_INSERT }
+ * - default: DO_NOT_INSERT
+ * </pre>
+ * @see IDEPlugin#INSERT
+ * @see IDEPlugin#DO_NOT_INSERT
+ */
+ public static final String FORMATTER_INSERT_NEW_LINE_BEFORE_WHILE_IN_DO_STATEMENT = IDEPlugin.PLUGIN_ID + ".formatter.insert_new_line_before_while_in_do_statement"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to insert a new line before the identifier in a function declaration
+ * - option id: "org.eclipse.cdt.core.formatter.insert_new_line_before_identifier_in_function_declaration"
+ * - possible values: { INSERT, DO_NOT_INSERT }
+ * - default: INSERT
+ * </pre>
+ * @see IDEPlugin#INSERT
+ * @see IDEPlugin#DO_NOT_INSERT
+ */
+ public static final String FORMATTER_INSERT_NEW_LINE_BEFORE_IDENTIFIER_IN_FUNCTION_DECLARATION = IDEPlugin.PLUGIN_ID + ".formatter.insert_new_line_before_identifier_in_function_declaration"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to insert a new line in an empty block
+ * - option id: "org.eclipse.cdt.core.formatter.insert_new_line_in_empty_block"
+ * - possible values: { INSERT, DO_NOT_INSERT }
+ * - default: INSERT
+ * </pre>
+ * @see IDEPlugin#INSERT
+ * @see IDEPlugin#DO_NOT_INSERT
+ */
+ public static final String FORMATTER_INSERT_NEW_LINE_IN_EMPTY_BLOCK = IDEPlugin.PLUGIN_ID + ".formatter.insert_new_line_in_empty_block"; //$NON-NLS-1$
+// /**
+// * <pre>
+// * FORMATTER / Option to insert a new line in an empty enum declaration
+// * - option id: "org.eclipse.cdt.core.formatter.insert_new_line_in_empty_enum_declaration"
+// * - possible values: { INSERT, DO_NOT_INSERT }
+// * - default: INSERT
+// * </pre>
+// * @see IDEPlugin#INSERT
+// * @see IDEPlugin#DO_NOT_INSERT
+// */
+// public static final String FORMATTER_INSERT_NEW_LINE_IN_EMPTY_ENUM_DECLARATION = IDEPlugin.PLUGIN_ID + ".formatter.insert_new_line_in_empty_enum_declaration"; //$NON-NLS-1$
+// /**
+// * <pre>
+// * FORMATTER / Option to insert a new line in an empty method body
+// * - option id: "org.eclipse.cdt.core.formatter.insert_new_line_in_empty_method_body"
+// * - possible values: { INSERT, DO_NOT_INSERT }
+// * - default: INSERT
+// * </pre>
+// * @see IDEPlugin#INSERT
+// * @see IDEPlugin#DO_NOT_INSERT
+// */
+// public static final String FORMATTER_INSERT_NEW_LINE_IN_EMPTY_METHOD_BODY = IDEPlugin.PLUGIN_ID + ".formatter.insert_new_line_in_empty_method_body"; //$NON-NLS-1$
+// /**
+// * <pre>
+// * FORMATTER / Option to insert a new line in an empty type declaration
+// * - option id: "org.eclipse.cdt.core.formatter.insert_new_line_in_empty_type_declaration"
+// * - possible values: { INSERT, DO_NOT_INSERT }
+// * - default: INSERT
+// * </pre>
+// * @see IDEPlugin#INSERT
+// * @see IDEPlugin#DO_NOT_INSERT
+// */
+// public static final String FORMATTER_INSERT_NEW_LINE_IN_EMPTY_TYPE_DECLARATION = IDEPlugin.PLUGIN_ID + ".formatter.insert_new_line_in_empty_type_declaration"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to insert a space after an assignment operator
+ * - option id: "org.eclipse.cdt.core.formatter.insert_space_after_assignment_operator"
+ * - possible values: { INSERT, DO_NOT_INSERT }
+ * - default: INSERT
+ * </pre>
+ * @see IDEPlugin#INSERT
+ * @see IDEPlugin#DO_NOT_INSERT
+ */
+ public static final String FORMATTER_INSERT_SPACE_AFTER_ASSIGNMENT_OPERATOR = IDEPlugin.PLUGIN_ID + ".formatter.insert_space_after_assignment_operator"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to insert a space after a binary operator
+ * - option id: "org.eclipse.cdt.core.formatter.insert_space_after_binary_operator"
+ * - possible values: { INSERT, DO_NOT_INSERT }
+ * - default: INSERT
+ * </pre>
+ * @see IDEPlugin#INSERT
+ * @see IDEPlugin#DO_NOT_INSERT
+ */
+ public static final String FORMATTER_INSERT_SPACE_AFTER_BINARY_OPERATOR = IDEPlugin.PLUGIN_ID + ".formatter.insert_space_after_binary_operator"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to insert a space after the closing angle bracket in template arguments
+ * - option id: "org.eclipse.cdt.core.formatter.insert_space_after_closing_angle_bracket_in_template_arguments"
+ * - possible values: { INSERT, DO_NOT_INSERT }
+ * - default: INSERT
+ * </pre>
+ * @see IDEPlugin#INSERT
+ * @see IDEPlugin#DO_NOT_INSERT
+ */
+ public static final String FORMATTER_INSERT_SPACE_AFTER_CLOSING_ANGLE_BRACKET_IN_TEMPLATE_ARGUMENTS = IDEPlugin.PLUGIN_ID + ".formatter.insert_space_after_closing_angle_bracket_in_template_arguments"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to insert a space after the closing angle bracket in template parameters
+ * - option id: "org.eclipse.cdt.core.formatter.insert_space_after_closing_angle_bracket_in_template_parameters"
+ * - possible values: { INSERT, DO_NOT_INSERT }
+ * - default: INSERT
+ * </pre>
+ * @see IDEPlugin#INSERT
+ * @see IDEPlugin#DO_NOT_INSERT
+ */
+ public static final String FORMATTER_INSERT_SPACE_AFTER_CLOSING_ANGLE_BRACKET_IN_TEMPLATE_PARAMETERS = IDEPlugin.PLUGIN_ID + ".formatter.insert_space_after_closing_angle_bracket_in_template_parameters"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to insert a space after the closing brace of a block
+ * - option id: "org.eclipse.cdt.core.formatter.insert_space_after_closing_brace_in_block"
+ * - possible values: { INSERT, DO_NOT_INSERT }
+ * - default: INSERT
+ * </pre>
+ * @see IDEPlugin#INSERT
+ * @see IDEPlugin#DO_NOT_INSERT
+ */
+ public static final String FORMATTER_INSERT_SPACE_AFTER_CLOSING_BRACE_IN_BLOCK = IDEPlugin.PLUGIN_ID + ".formatter.insert_space_after_closing_brace_in_block"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to insert a space after the closing parenthesis of a cast expression
+ * - option id: "org.eclipse.cdt.core.formatter.insert_space_after_closing_paren_in_cast"
+ * - possible values: { INSERT, DO_NOT_INSERT }
+ * - default: INSERT
+ * </pre>
+ * @see IDEPlugin#INSERT
+ * @see IDEPlugin#DO_NOT_INSERT
+ */
+ public static final String FORMATTER_INSERT_SPACE_AFTER_CLOSING_PAREN_IN_CAST = IDEPlugin.PLUGIN_ID + ".formatter.insert_space_after_closing_paren_in_cast"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to insert a space after colon in a base clause of a type definition
+ * - option id: "org.eclipse.cdt.core.formatter.insert_space_after_colon_in_base_clause"
+ * - possible values: { INSERT, DO_NOT_INSERT }
+ * - default: INSERT
+ * </pre>
+ * @see IDEPlugin#INSERT
+ * @see IDEPlugin#DO_NOT_INSERT
+ */
+ public static final String FORMATTER_INSERT_SPACE_AFTER_COLON_IN_BASE_CLAUSE = IDEPlugin.PLUGIN_ID + ".formatter.insert_space_after_colon_in_base_clause"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to insert a space after colon in a case statement when a opening brace follows the colon
+ * - option id: "org.eclipse.cdt.core.formatter.insert_space_after_colon_in_case"
+ * - possible values: { INSERT, DO_NOT_INSERT }
+ * - default: INSERT
+ * </pre>
+ * @see IDEPlugin#INSERT
+ * @see IDEPlugin#DO_NOT_INSERT
+ */
+ public static final String FORMATTER_INSERT_SPACE_AFTER_COLON_IN_CASE = IDEPlugin.PLUGIN_ID + ".formatter.insert_space_after_colon_in_case"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to insert a space after the colon in a conditional expression
+ * - option id: "org.eclipse.cdt.core.formatter.insert_space_after_colon_in_conditional"
+ * - possible values: { INSERT, DO_NOT_INSERT }
+ * - default: INSERT
+ * </pre>
+ * @see IDEPlugin#INSERT
+ * @see IDEPlugin#DO_NOT_INSERT
+ */
+ public static final String FORMATTER_INSERT_SPACE_AFTER_COLON_IN_CONDITIONAL = IDEPlugin.PLUGIN_ID + ".formatter.insert_space_after_colon_in_conditional"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to insert a space after the colon in a labeled statement
+ * - option id: "org.eclipse.cdt.core.formatter.insert_space_after_colon_in_labeled_statement"
+ * - possible values: { INSERT, DO_NOT_INSERT }
+ * - default: INSERT
+ * </pre>
+ * @see IDEPlugin#INSERT
+ * @see IDEPlugin#DO_NOT_INSERT
+ */
+ public static final String FORMATTER_INSERT_SPACE_AFTER_COLON_IN_LABELED_STATEMENT = IDEPlugin.PLUGIN_ID + ".formatter.insert_space_after_colon_in_labeled_statement"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to insert a space after the comma in an initializer list
+ * - option id: "org.eclipse.cdt.core.formatter.insert_space_after_comma_in_array_initializer"
+ * - possible values: { INSERT, DO_NOT_INSERT }
+ * - default: INSERT
+ * </pre>
+ * @see IDEPlugin#INSERT
+ * @see IDEPlugin#DO_NOT_INSERT
+ */
+ public static final String FORMATTER_INSERT_SPACE_AFTER_COMMA_IN_INITIALIZER_LIST = IDEPlugin.PLUGIN_ID + ".formatter.insert_space_after_comma_in_array_initializer"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to insert a space after the comma in enum declarations
+ * - option id: "org.eclipse.cdt.core.formatter.insert_space_after_comma_in_enum_declarations"
+ * - possible values: { INSERT, DO_NOT_INSERT }
+ * - default: INSERT
+ * </pre>
+ * @see IDEPlugin#INSERT
+ * @see IDEPlugin#DO_NOT_INSERT
+ */
+ public static final String FORMATTER_INSERT_SPACE_AFTER_COMMA_IN_ENUM_DECLARATIONS = IDEPlugin.PLUGIN_ID + ".formatter.insert_space_after_comma_in_enum_declarations"; //$NON-NLS-1$
+// /**
+// * <pre>
+// * FORMATTER / Option to insert a space after the comma in the increments of a for statement
+// * - option id: "org.eclipse.cdt.core.formatter.insert_space_after_comma_in_for_increments"
+// * - possible values: { INSERT, DO_NOT_INSERT }
+// * - default: INSERT
+// * </pre>
+// * @see IDEPlugin#INSERT
+// * @see IDEPlugin#DO_NOT_INSERT
+// */
+// public static final String FORMATTER_INSERT_SPACE_AFTER_COMMA_IN_FOR_INCREMENTS = IDEPlugin.PLUGIN_ID + ".formatter.insert_space_after_comma_in_for_increments"; //$NON-NLS-1$
+// /**
+// * <pre>
+// * FORMATTER / Option to insert a space after the comma in the initializations of a for statement
+// * - option id: "org.eclipse.cdt.core.formatter.insert_space_after_comma_in_for_inits"
+// * - possible values: { INSERT, DO_NOT_INSERT }
+// * - default: INSERT
+// * </pre>
+// * @see IDEPlugin#INSERT
+// * @see IDEPlugin#DO_NOT_INSERT
+// */
+// public static final String FORMATTER_INSERT_SPACE_AFTER_COMMA_IN_FOR_INITS = IDEPlugin.PLUGIN_ID + ".formatter.insert_space_after_comma_in_for_inits"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to insert a space after the comma in the parameters of a method declaration
+ * - option id: "org.eclipse.cdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters"
+ * - possible values: { INSERT, DO_NOT_INSERT }
+ * - default: INSERT
+ * </pre>
+ * @see IDEPlugin#INSERT
+ * @see IDEPlugin#DO_NOT_INSERT
+ */
+ public static final String FORMATTER_INSERT_SPACE_AFTER_COMMA_IN_METHOD_DECLARATION_PARAMETERS = IDEPlugin.PLUGIN_ID + ".formatter.insert_space_after_comma_in_method_declaration_parameters"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to insert a space after the comma in the exception names in a throws clause of a method declaration
+ * - option id: "org.eclipse.cdt.core.formatter.insert_space_after_comma_in_method_declaration_throws"
+ * - possible values: { INSERT, DO_NOT_INSERT }
+ * - default: INSERT
+ * </pre>
+ * @see IDEPlugin#INSERT
+ * @see IDEPlugin#DO_NOT_INSERT
+ */
+ public static final String FORMATTER_INSERT_SPACE_AFTER_COMMA_IN_METHOD_DECLARATION_THROWS = IDEPlugin.PLUGIN_ID + ".formatter.insert_space_after_comma_in_method_declaration_throws"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to insert a space after the comma in the arguments of a method invocation
+ * - option id: "org.eclipse.cdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments"
+ * - possible values: { INSERT, DO_NOT_INSERT }
+ * - default: INSERT
+ * </pre>
+ * @see IDEPlugin#INSERT
+ * @see IDEPlugin#DO_NOT_INSERT
+ */
+ public static final String FORMATTER_INSERT_SPACE_AFTER_COMMA_IN_METHOD_INVOCATION_ARGUMENTS = IDEPlugin.PLUGIN_ID + ".formatter.insert_space_after_comma_in_method_invocation_arguments"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to insert a space after the comma in a declarator list
+ * - option id: "org.eclipse.cdt.core.formatter.insert_space_after_comma_in_declarator_list"
+ * - possible values: { INSERT, DO_NOT_INSERT }
+ * - default: INSERT
+ * </pre>
+ * @see IDEPlugin#INSERT
+ * @see IDEPlugin#DO_NOT_INSERT
+ */
+ public static final String FORMATTER_INSERT_SPACE_AFTER_COMMA_IN_DECLARATOR_LIST = IDEPlugin.PLUGIN_ID + ".formatter.insert_space_after_comma_in_declarator_list"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to insert a space after the comma in expression list
+ * - option id: "org.eclipse.cdt.core.formatter.insert_space_after_comma_in_expression_list"
+ * - possible values: { INSERT, DO_NOT_INSERT }
+ * - default: INSERT
+ * </pre>
+ * @see IDEPlugin#INSERT
+ * @see IDEPlugin#DO_NOT_INSERT
+ */
+ public static final String FORMATTER_INSERT_SPACE_AFTER_COMMA_IN_EXPRESSION_LIST = IDEPlugin.PLUGIN_ID + ".formatter.insert_space_after_comma_in_expression_list"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to insert a space after the comma in base type names of a type header
+ * - option id: "org.eclipse.cdt.core.formatter.insert_space_after_comma_in_base_types"
+ * - possible values: { INSERT, DO_NOT_INSERT }
+ * - default: INSERT
+ * </pre>
+ * @see IDEPlugin#INSERT
+ * @see IDEPlugin#DO_NOT_INSERT
+ */
+ public static final String FORMATTER_INSERT_SPACE_AFTER_COMMA_IN_BASE_TYPES = IDEPlugin.PLUGIN_ID + ".formatter.insert_space_after_comma_in_base_types"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to insert a space after the comma in template arguments
+ * - option id: "org.eclipse.cdt.core.formatter.insert_space_after_comma_in_template_arguments"
+ * - possible values: { INSERT, DO_NOT_INSERT }
+ * - default: INSERT
+ * </pre>
+ * @see IDEPlugin#INSERT
+ * @see IDEPlugin#DO_NOT_INSERT
+ */
+ public static final String FORMATTER_INSERT_SPACE_AFTER_COMMA_IN_TEMPLATE_ARGUMENTS = IDEPlugin.PLUGIN_ID + ".formatter.insert_space_after_comma_in_template_arguments"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to insert a space after the comma in template parameters
+ * - option id: "org.eclipse.cdt.core.formatter.insert_space_after_comma_in_template_parameters"
+ * - possible values: { INSERT, DO_NOT_INSERT }
+ * - default: INSERT
+ * </pre>
+ * @see IDEPlugin#INSERT
+ * @see IDEPlugin#DO_NOT_INSERT
+ */
+ public static final String FORMATTER_INSERT_SPACE_AFTER_COMMA_IN_TEMPLATE_PARAMETERS = IDEPlugin.PLUGIN_ID + ".formatter.insert_space_after_comma_in_template_parameters"; //$NON-NLS-1$
+// /**
+// * <pre>
+// * FORMATTER / Option to insert a space after ellipsis
+// * - option id: "org.eclipse.cdt.core.formatter.insert_space_after_ellipsis"
+// * - possible values: { INSERT, DO_NOT_INSERT }
+// * - default: INSERT
+// * </pre>
+// * @see IDEPlugin#INSERT
+// * @see IDEPlugin#DO_NOT_INSERT
+// */
+// public static final String FORMATTER_INSERT_SPACE_AFTER_ELLIPSIS = IDEPlugin.PLUGIN_ID + ".formatter.insert_space_after_ellipsis"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to insert a space after the opening angle bracket in template arguments
+ * - option id: "org.eclipse.cdt.core.formatter.insert_space_after_opening_angle_bracket_in_template_arguments"
+ * - possible values: { INSERT, DO_NOT_INSERT }
+ * - default: DO_NOT_INSERT
+ * </pre>
+ * @see IDEPlugin#INSERT
+ * @see IDEPlugin#DO_NOT_INSERT
+ */
+ public static final String FORMATTER_INSERT_SPACE_AFTER_OPENING_ANGLE_BRACKET_IN_TEMPLATE_ARGUMENTS = IDEPlugin.PLUGIN_ID + ".formatter.insert_space_after_opening_angle_bracket_in_template_arguments";//$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to insert a space after the opening angle bracket in template parameters
+ * - option id: "org.eclipse.cdt.core.formatter.insert_space_after_opening_angle_bracket_in_template_parameters"
+ * - possible values: { INSERT, DO_NOT_INSERT }
+ * - default: DO_NOT_INSERT
+ * </pre>
+ * @see IDEPlugin#INSERT
+ * @see IDEPlugin#DO_NOT_INSERT
+ */
+ public static final String FORMATTER_INSERT_SPACE_AFTER_OPENING_ANGLE_BRACKET_IN_TEMPLATE_PARAMETERS = IDEPlugin.PLUGIN_ID + ".formatter.insert_space_after_opening_angle_bracket_in_template_parameters";//$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to insert a space after the opening brace in an initializer list
+ * - option id: "org.eclipse.cdt.core.formatter.insert_space_after_opening_brace_in_array_initializer"
+ * - possible values: { INSERT, DO_NOT_INSERT }
+ * - default: DO_NOT_INSERT
+ * </pre>
+ * @see IDEPlugin#INSERT
+ * @see IDEPlugin#DO_NOT_INSERT
+ */
+ public static final String FORMATTER_INSERT_SPACE_AFTER_OPENING_BRACE_IN_INITIALIZER_LIST = IDEPlugin.PLUGIN_ID + ".formatter.insert_space_after_opening_brace_in_array_initializer"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to insert a space after the opening bracket
+ * - option id: "org.eclipse.cdt.core.formatter.insert_space_after_opening_bracket"
+ * - possible values: { INSERT, DO_NOT_INSERT }
+ * - default: DO_NOT_INSERT
+ * </pre>
+ * @see IDEPlugin#INSERT
+ * @see IDEPlugin#DO_NOT_INSERT
+ */
+ public static final String FORMATTER_INSERT_SPACE_AFTER_OPENING_BRACKET = IDEPlugin.PLUGIN_ID + ".formatter.insert_space_after_opening_bracket";//$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to insert a space after the opening parenthesis in a cast expression
+ * - option id: "org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_cast"
+ * - possible values: { INSERT, DO_NOT_INSERT }
+ * - default: DO_NOT_INSERT
+ * </pre>
+ * @see IDEPlugin#INSERT
+ * @see IDEPlugin#DO_NOT_INSERT
+ */
+ public static final String FORMATTER_INSERT_SPACE_AFTER_OPENING_PAREN_IN_CAST = IDEPlugin.PLUGIN_ID + ".formatter.insert_space_after_opening_paren_in_cast"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to insert a space after the opening parenthesis in a catch
+ * - option id: "org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_catch"
+ * - possible values: { INSERT, DO_NOT_INSERT }
+ * - default: DO_NOT_INSERT
+ * </pre>
+ * @see IDEPlugin#INSERT
+ * @see IDEPlugin#DO_NOT_INSERT
+ */
+ public static final String FORMATTER_INSERT_SPACE_AFTER_OPENING_PAREN_IN_CATCH = IDEPlugin.PLUGIN_ID + ".formatter.insert_space_after_opening_paren_in_catch"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to insert a space after the opening parenthesis in a for statement
+ * - option id: "org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_for"
+ * - possible values: { INSERT, DO_NOT_INSERT }
+ * - default: DO_NOT_INSERT
+ * </pre>
+ * @see IDEPlugin#INSERT
+ * @see IDEPlugin#DO_NOT_INSERT
+ */
+ public static final String FORMATTER_INSERT_SPACE_AFTER_OPENING_PAREN_IN_FOR = IDEPlugin.PLUGIN_ID + ".formatter.insert_space_after_opening_paren_in_for"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to insert a space after the opening parenthesis in an if statement
+ * - option id: "org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_if"
+ * - possible values: { INSERT, DO_NOT_INSERT }
+ * - default: DO_NOT_INSERT
+ * </pre>
+ * @see IDEPlugin#INSERT
+ * @see IDEPlugin#DO_NOT_INSERT
+ */
+ public static final String FORMATTER_INSERT_SPACE_AFTER_OPENING_PAREN_IN_IF = IDEPlugin.PLUGIN_ID + ".formatter.insert_space_after_opening_paren_in_if"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to insert a space after the opening parenthesis in a method declaration
+ * - option id: "org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_method_declaration"
+ * - possible values: { INSERT, DO_NOT_INSERT }
+ * - default: DO_NOT_INSERT
+ * </pre>
+ * @see IDEPlugin#INSERT
+ * @see IDEPlugin#DO_NOT_INSERT
+ */
+ public static final String FORMATTER_INSERT_SPACE_AFTER_OPENING_PAREN_IN_METHOD_DECLARATION = IDEPlugin.PLUGIN_ID + ".formatter.insert_space_after_opening_paren_in_method_declaration"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to insert a space after the opening parenthesis in a method invocation
+ * - option id: "org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_method_invocation"
+ * - possible values: { INSERT, DO_NOT_INSERT }
+ * - default: DO_NOT_INSERT
+ * </pre>
+ * @see IDEPlugin#INSERT
+ * @see IDEPlugin#DO_NOT_INSERT
+ */
+ public static final String FORMATTER_INSERT_SPACE_AFTER_OPENING_PAREN_IN_METHOD_INVOCATION = IDEPlugin.PLUGIN_ID + ".formatter.insert_space_after_opening_paren_in_method_invocation"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to insert a space after the opening parenthesis in an exception specification
+ * - option id: "org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_exception_specification"
+ * - possible values: { INSERT, DO_NOT_INSERT }
+ * - default: DO_NOT_INSERT
+ * </pre>
+ * @see IDEPlugin#INSERT
+ * @see IDEPlugin#DO_NOT_INSERT
+ * @since 5.1
+ */
+ public static final String FORMATTER_INSERT_SPACE_AFTER_OPENING_PAREN_IN_EXCEPTION_SPECIFICATION = IDEPlugin.PLUGIN_ID + ".formatter.insert_space_after_opening_paren_in_exception_specification"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to insert a space after the opening parenthesis in a parenthesized expression
+ * - option id: "org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression"
+ * - possible values: { INSERT, DO_NOT_INSERT }
+ * - default: DO_NOT_INSERT
+ * </pre>
+ * @see IDEPlugin#INSERT
+ * @see IDEPlugin#DO_NOT_INSERT
+ */
+ public static final String FORMATTER_INSERT_SPACE_AFTER_OPENING_PAREN_IN_PARENTHESIZED_EXPRESSION = IDEPlugin.PLUGIN_ID + ".formatter.insert_space_after_opening_paren_in_parenthesized_expression"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to insert a space after the opening parenthesis in a switch statement
+ * - option id: "org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_switch"
+ * - possible values: { INSERT, DO_NOT_INSERT }
+ * - default: DO_NOT_INSERT
+ * </pre>
+ * @see IDEPlugin#INSERT
+ * @see IDEPlugin#DO_NOT_INSERT
+ */
+ public static final String FORMATTER_INSERT_SPACE_AFTER_OPENING_PAREN_IN_SWITCH = IDEPlugin.PLUGIN_ID + ".formatter.insert_space_after_opening_paren_in_switch"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to insert a space after the opening parenthesis in a while statement
+ * - option id: "org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_while"
+ * - possible values: { INSERT, DO_NOT_INSERT }
+ * - default: DO_NOT_INSERT
+ * </pre>
+ * @see IDEPlugin#INSERT
+ * @see IDEPlugin#DO_NOT_INSERT
+ */
+ public static final String FORMATTER_INSERT_SPACE_AFTER_OPENING_PAREN_IN_WHILE = IDEPlugin.PLUGIN_ID + ".formatter.insert_space_after_opening_paren_in_while"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to insert a space after a postfix operator
+ * - option id: "org.eclipse.cdt.core.formatter.insert_space_after_postfix_operator"
+ * - possible values: { INSERT, DO_NOT_INSERT }
+ * - default: DO_NOT_INSERT
+ * </pre>
+ * @see IDEPlugin#INSERT
+ * @see IDEPlugin#DO_NOT_INSERT
+ */
+ public static final String FORMATTER_INSERT_SPACE_AFTER_POSTFIX_OPERATOR = IDEPlugin.PLUGIN_ID + ".formatter.insert_space_after_postfix_operator"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to insert a space after a prefix operator
+ * - option id: "org.eclipse.cdt.core.formatter.insert_space_after_prefix_operator"
+ * - possible values: { INSERT, DO_NOT_INSERT }
+ * - default: DO_NOT_INSERT
+ * </pre>
+ * @see IDEPlugin#INSERT
+ * @see IDEPlugin#DO_NOT_INSERT
+ */
+ public static final String FORMATTER_INSERT_SPACE_AFTER_PREFIX_OPERATOR = IDEPlugin.PLUGIN_ID + ".formatter.insert_space_after_prefix_operator"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to insert a space after question mark in a conditional expression
+ * - option id: "org.eclipse.cdt.core.formatter.insert_space_after_question_in_conditional"
+ * - possible values: { INSERT, DO_NOT_INSERT }
+ * - default: DO_NOT_INSERT
+ * </pre>
+ * @see IDEPlugin#INSERT
+ * @see IDEPlugin#DO_NOT_INSERT
+ */
+ public static final String FORMATTER_INSERT_SPACE_AFTER_QUESTION_IN_CONDITIONAL = IDEPlugin.PLUGIN_ID + ".formatter.insert_space_after_question_in_conditional"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to insert a space after semicolon in a for statement
+ * - option id: "org.eclipse.cdt.core.formatter.insert_space_after_semicolon_in_for"
+ * - possible values: { INSERT, DO_NOT_INSERT }
+ * - default: INSERT
+ * </pre>
+ * @see IDEPlugin#INSERT
+ * @see IDEPlugin#DO_NOT_INSERT
+ */
+ public static final String FORMATTER_INSERT_SPACE_AFTER_SEMICOLON_IN_FOR = IDEPlugin.PLUGIN_ID + ".formatter.insert_space_after_semicolon_in_for"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to insert a space after an unary operator
+ * - option id: "org.eclipse.cdt.core.formatter.insert_space_after_unary_operator"
+ * - possible values: { INSERT, DO_NOT_INSERT }
+ * - default: DO_NOT_INSERT
+ * </pre>
+ * @see IDEPlugin#INSERT
+ * @see IDEPlugin#DO_NOT_INSERT
+ */
+ public static final String FORMATTER_INSERT_SPACE_AFTER_UNARY_OPERATOR = IDEPlugin.PLUGIN_ID + ".formatter.insert_space_after_unary_operator"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to insert a space before an assignment operator
+ * - option id: "org.eclipse.cdt.core.formatter.insert_space_before_assignment_operator"
+ * - possible values: { INSERT, DO_NOT_INSERT }
+ * - default: INSERT
+ * </pre>
+ * @see IDEPlugin#INSERT
+ * @see IDEPlugin#DO_NOT_INSERT
+ */
+ public static final String FORMATTER_INSERT_SPACE_BEFORE_ASSIGNMENT_OPERATOR = IDEPlugin.PLUGIN_ID + ".formatter.insert_space_before_assignment_operator"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to insert a space before an binary operator
+ * - option id: "org.eclipse.cdt.core.formatter.insert_space_before_binary_operator"
+ * - possible values: { INSERT, DO_NOT_INSERT }
+ * - default: DO_NOT_INSERT
+ * </pre>
+ * @see IDEPlugin#INSERT
+ * @see IDEPlugin#DO_NOT_INSERT
+ */
+ public static final String FORMATTER_INSERT_SPACE_BEFORE_BINARY_OPERATOR = IDEPlugin.PLUGIN_ID + ".formatter.insert_space_before_binary_operator"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to insert a space before the closing angle bracket in template arguments
+ * - option id: "org.eclipse.cdt.core.formatter.insert_space_before_closing_angle_bracket_in_template_arguments"
+ * - possible values: { INSERT, DO_NOT_INSERT }
+ * - default: DO_NOT_INSERT
+ * </pre>
+ * @see IDEPlugin#INSERT
+ * @see IDEPlugin#DO_NOT_INSERT
+ */
+ public static final String FORMATTER_INSERT_SPACE_BEFORE_CLOSING_ANGLE_BRACKET_IN_TEMPLATE_ARGUMENTS = IDEPlugin.PLUGIN_ID + ".formatter.insert_space_before_closing_angle_bracket_in_template_arguments"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to insert a space before the closing angle bracket in template parameters
+ * - option id: "org.eclipse.cdt.core.formatter.insert_space_before_closing_angle_bracket_in_template_parameters"
+ * - possible values: { INSERT, DO_NOT_INSERT }
+ * - default: DO_NOT_INSERT
+ * </pre>
+ * @see IDEPlugin#INSERT
+ * @see IDEPlugin#DO_NOT_INSERT
+ */
+ public static final String FORMATTER_INSERT_SPACE_BEFORE_CLOSING_ANGLE_BRACKET_IN_TEMPLATE_PARAMETERS = IDEPlugin.PLUGIN_ID + ".formatter.insert_space_before_closing_angle_bracket_in_template_parameters"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to insert a space before the closing brace in an initializer list
+ * - option id: "org.eclipse.cdt.core.formatter.insert_space_before_closing_brace_in_array_initializer"
+ * - possible values: { INSERT, DO_NOT_INSERT }
+ * - default: DO_NOT_INSERT
+ * </pre>
+ * @see IDEPlugin#INSERT
+ * @see IDEPlugin#DO_NOT_INSERT
+ */
+ public static final String FORMATTER_INSERT_SPACE_BEFORE_CLOSING_BRACE_IN_INITIALIZER_LIST = IDEPlugin.PLUGIN_ID + ".formatter.insert_space_before_closing_brace_in_array_initializer"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to insert a space before the closing bracket
+ * - option id: "org.eclipse.cdt.core.formatter.insert_space_before_closing_bracket"
+ * - possible values: { INSERT, DO_NOT_INSERT }
+ * - default: DO_NOT_INSERT
+ * </pre>
+ * @see IDEPlugin#INSERT
+ * @see IDEPlugin#DO_NOT_INSERT
+ */
+ public static final String FORMATTER_INSERT_SPACE_BEFORE_CLOSING_BRACKET = IDEPlugin.PLUGIN_ID + ".formatter.insert_space_before_closing_bracket";//$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to insert a space before the closing parenthesis in a cast expression
+ * - option id: "org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_cast"
+ * - possible values: { INSERT, DO_NOT_INSERT }
+ * - default: DO_NOT_INSERT
+ * </pre>
+ * @see IDEPlugin#INSERT
+ * @see IDEPlugin#DO_NOT_INSERT
+ */
+ public static final String FORMATTER_INSERT_SPACE_BEFORE_CLOSING_PAREN_IN_CAST = IDEPlugin.PLUGIN_ID + ".formatter.insert_space_before_closing_paren_in_cast"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to insert a space before the closing parenthesis in a catch
+ * - option id: "org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_catch"
+ * - possible values: { INSERT, DO_NOT_INSERT }
+ * - default: DO_NOT_INSERT
+ * </pre>
+ * @see IDEPlugin#INSERT
+ * @see IDEPlugin#DO_NOT_INSERT
+ */
+ public static final String FORMATTER_INSERT_SPACE_BEFORE_CLOSING_PAREN_IN_CATCH = IDEPlugin.PLUGIN_ID + ".formatter.insert_space_before_closing_paren_in_catch"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to insert a space before the closing parenthesis in a for statement
+ * - option id: "org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_for"
+ * - possible values: { INSERT, DO_NOT_INSERT }
+ * - default: DO_NOT_INSERT
+ * </pre>
+ * @see IDEPlugin#INSERT
+ * @see IDEPlugin#DO_NOT_INSERT
+ */
+ public static final String FORMATTER_INSERT_SPACE_BEFORE_CLOSING_PAREN_IN_FOR = IDEPlugin.PLUGIN_ID + ".formatter.insert_space_before_closing_paren_in_for"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to insert a space before the closing parenthesis in an if statement
+ * - option id: "org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_if"
+ * - possible values: { INSERT, DO_NOT_INSERT }
+ * - default: DO_NOT_INSERT
+ * </pre>
+ * @see IDEPlugin#INSERT
+ * @see IDEPlugin#DO_NOT_INSERT
+ */
+ public static final String FORMATTER_INSERT_SPACE_BEFORE_CLOSING_PAREN_IN_IF = IDEPlugin.PLUGIN_ID + ".formatter.insert_space_before_closing_paren_in_if"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to insert a space before the closing parenthesis in a method declaration
+ * - option id: "org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_method_declaration"
+ * - possible values: { INSERT, DO_NOT_INSERT }
+ * - default: DO_NOT_INSERT
+ * </pre>
+ * @see IDEPlugin#INSERT
+ * @see IDEPlugin#DO_NOT_INSERT
+ */
+ public static final String FORMATTER_INSERT_SPACE_BEFORE_CLOSING_PAREN_IN_METHOD_DECLARATION = IDEPlugin.PLUGIN_ID + ".formatter.insert_space_before_closing_paren_in_method_declaration"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to insert a space before the closing parenthesis in a method invocation
+ * - option id: "org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_method_invocation"
+ * - possible values: { INSERT, DO_NOT_INSERT }
+ * - default: DO_NOT_INSERT
+ * </pre>
+ * @see IDEPlugin#INSERT
+ * @see IDEPlugin#DO_NOT_INSERT
+ */
+ public static final String FORMATTER_INSERT_SPACE_BEFORE_CLOSING_PAREN_IN_METHOD_INVOCATION = IDEPlugin.PLUGIN_ID + ".formatter.insert_space_before_closing_paren_in_method_invocation"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to insert a space before the closing parenthesis in an exception specification
+ * - option id: "org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_exception_specification"
+ * - possible values: { INSERT, DO_NOT_INSERT }
+ * - default: DO_NOT_INSERT
+ * </pre>
+ * @see IDEPlugin#INSERT
+ * @see IDEPlugin#DO_NOT_INSERT
+ * @since 5.1
+ */
+ public static final String FORMATTER_INSERT_SPACE_BEFORE_CLOSING_PAREN_IN_EXCEPTION_SPECIFICATION = IDEPlugin.PLUGIN_ID + ".formatter.insert_space_before_closing_paren_in_exception_specification"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to insert a space before the closing parenthesis in a parenthesized expression
+ * - option id: "org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression"
+ * - possible values: { INSERT, DO_NOT_INSERT }
+ * - default: DO_NOT_INSERT
+ * </pre>
+ * @see IDEPlugin#INSERT
+ * @see IDEPlugin#DO_NOT_INSERT
+ */
+ public static final String FORMATTER_INSERT_SPACE_BEFORE_CLOSING_PAREN_IN_PARENTHESIZED_EXPRESSION = IDEPlugin.PLUGIN_ID + ".formatter.insert_space_before_closing_paren_in_parenthesized_expression"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to insert a space before the closing parenthesis in a switch statement
+ * - option id: "org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_switch"
+ * - possible values: { INSERT, DO_NOT_INSERT }
+ * - default: DO_NOT_INSERT
+ * </pre>
+ * @see IDEPlugin#INSERT
+ * @see IDEPlugin#DO_NOT_INSERT
+ */
+ public static final String FORMATTER_INSERT_SPACE_BEFORE_CLOSING_PAREN_IN_SWITCH = IDEPlugin.PLUGIN_ID + ".formatter.insert_space_before_closing_paren_in_switch"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to insert a space before the closing parenthesis in a while statement
+ * - option id: "org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_while"
+ * - possible values: { INSERT, DO_NOT_INSERT }
+ * - default: DO_NOT_INSERT
+ * </pre>
+ * @see IDEPlugin#INSERT
+ * @see IDEPlugin#DO_NOT_INSERT
+ */
+ public static final String FORMATTER_INSERT_SPACE_BEFORE_CLOSING_PAREN_IN_WHILE = IDEPlugin.PLUGIN_ID + ".formatter.insert_space_before_closing_paren_in_while"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to insert a space before colon in a base clause of a type definition
+ * - option id: "org.eclipse.cdt.core.formatter.insert_space_before_colon_in_base_clause"
+ * - possible values: { INSERT, DO_NOT_INSERT }
+ * - default: INSERT
+ * </pre>
+ * @see IDEPlugin#INSERT
+ * @see IDEPlugin#DO_NOT_INSERT
+ */
+ public static final String FORMATTER_INSERT_SPACE_BEFORE_COLON_IN_BASE_CLAUSE = IDEPlugin.PLUGIN_ID + ".formatter.insert_space_before_colon_in_base_clause"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to insert a space before colon in a case statement
+ * - option id: "org.eclipse.cdt.core.formatter.insert_space_before_colon_in_case"
+ * - possible values: { INSERT, DO_NOT_INSERT }
+ * - default: INSERT
+ * </pre>
+ * @see IDEPlugin#INSERT
+ * @see IDEPlugin#DO_NOT_INSERT
+ */
+ public static final String FORMATTER_INSERT_SPACE_BEFORE_COLON_IN_CASE = IDEPlugin.PLUGIN_ID + ".formatter.insert_space_before_colon_in_case"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to insert a space before colon in a conditional expression
+ * - option id: "org.eclipse.cdt.core.formatter.insert_space_before_colon_in_conditional"
+ * - possible values: { INSERT, DO_NOT_INSERT }
+ * - default: INSERT
+ * </pre>
+ * @see IDEPlugin#INSERT
+ * @see IDEPlugin#DO_NOT_INSERT
+ */
+ public static final String FORMATTER_INSERT_SPACE_BEFORE_COLON_IN_CONDITIONAL = IDEPlugin.PLUGIN_ID + ".formatter.insert_space_before_colon_in_conditional"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to insert a space before colon in a default statement
+ * - option id: "org.eclipse.cdt.core.formatter.insert_space_before_colon_in_default"
+ * - possible values: { INSERT, DO_NOT_INSERT }
+ * - default: INSERT
+ * </pre>
+ * @see IDEPlugin#INSERT
+ * @see IDEPlugin#DO_NOT_INSERT
+ */
+ public static final String FORMATTER_INSERT_SPACE_BEFORE_COLON_IN_DEFAULT = IDEPlugin.PLUGIN_ID + ".formatter.insert_space_before_colon_in_default"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to insert a space before colon in a labeled statement
+ * - option id: "org.eclipse.cdt.core.formatter.insert_space_before_colon_in_labeled_statement"
+ * - possible values: { INSERT, DO_NOT_INSERT }
+ * - default: INSERT
+ * </pre>
+ * @see IDEPlugin#INSERT
+ * @see IDEPlugin#DO_NOT_INSERT
+ */
+ public static final String FORMATTER_INSERT_SPACE_BEFORE_COLON_IN_LABELED_STATEMENT = IDEPlugin.PLUGIN_ID + ".formatter.insert_space_before_colon_in_labeled_statement"; //$NON-NLS-1$
+// /**
+// * <pre>
+// * FORMATTER / Option to insert a space before comma in an allocation expression
+// * - option id: "org.eclipse.cdt.core.formatter.insert_space_before_comma_in_allocation_expression"
+// * - possible values: { INSERT, DO_NOT_INSERT }
+// * - default: DO_NOT_INSERT
+// * </pre>
+// * @see IDEPlugin#INSERT
+// * @see IDEPlugin#DO_NOT_INSERT
+// */
+// public static final String FORMATTER_INSERT_SPACE_BEFORE_COMMA_IN_ALLOCATION_EXPRESSION = IDEPlugin.PLUGIN_ID + ".formatter.insert_space_before_comma_in_allocation_expression"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to insert a space before comma in an initializer list
+ * - option id: "org.eclipse.cdt.core.formatter.insert_space_before_comma_in_array_initializer"
+ * - possible values: { INSERT, DO_NOT_INSERT }
+ * - default: DO_NOT_INSERT
+ * </pre>
+ * @see IDEPlugin#INSERT
+ * @see IDEPlugin#DO_NOT_INSERT
+ */
+ public static final String FORMATTER_INSERT_SPACE_BEFORE_COMMA_IN_INITIALIZER_LIST = IDEPlugin.PLUGIN_ID + ".formatter.insert_space_before_comma_in_array_initializer"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to insert a space before comma in enum declarations
+ * - option id: "org.eclipse.cdt.core.formatter.insert_space_before_comma_in_enum_declarations"
+ * - possible values: { INSERT, DO_NOT_INSERT }
+ * - default: DO_NOT_INSERT
+ * </pre>
+ * @see IDEPlugin#INSERT
+ * @see IDEPlugin#DO_NOT_INSERT
+ */
+ public static final String FORMATTER_INSERT_SPACE_BEFORE_COMMA_IN_ENUM_DECLARATIONS = IDEPlugin.PLUGIN_ID + ".formatter.insert_space_before_comma_in_enum_declarations"; //$NON-NLS-1$
+// /**
+// * <pre>
+// * FORMATTER / Option to insert a space before comma in the increments of a for statement
+// * - option id: "org.eclipse.cdt.core.formatter.insert_space_before_comma_in_for_increments"
+// * - possible values: { INSERT, DO_NOT_INSERT }
+// * - default: DO_NOT_INSERT
+// * </pre>
+// * @see IDEPlugin#INSERT
+// * @see IDEPlugin#DO_NOT_INSERT
+// */
+// public static final String FORMATTER_INSERT_SPACE_BEFORE_COMMA_IN_FOR_INCREMENTS = IDEPlugin.PLUGIN_ID + ".formatter.insert_space_before_comma_in_for_increments"; //$NON-NLS-1$
+// /**
+// * <pre>
+// * FORMATTER / Option to insert a space before comma in the initializations of a for statement
+// * - option id: "org.eclipse.cdt.core.formatter.insert_space_before_comma_in_for_inits"
+// * - possible values: { INSERT, DO_NOT_INSERT }
+// * - default: DO_NOT_INSERT
+// * </pre>
+// * @see IDEPlugin#INSERT
+// * @see IDEPlugin#DO_NOT_INSERT
+// */
+// public static final String FORMATTER_INSERT_SPACE_BEFORE_COMMA_IN_FOR_INITS = IDEPlugin.PLUGIN_ID + ".formatter.insert_space_before_comma_in_for_inits"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to insert a space before comma in the parameters of a method declaration
+ * - option id: "org.eclipse.cdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters"
+ * - possible values: { INSERT, DO_NOT_INSERT }
+ * - default: DO_NOT_INSERT
+ * </pre>
+ * @see IDEPlugin#INSERT
+ * @see IDEPlugin#DO_NOT_INSERT
+ */
+ public static final String FORMATTER_INSERT_SPACE_BEFORE_COMMA_IN_METHOD_DECLARATION_PARAMETERS = IDEPlugin.PLUGIN_ID + ".formatter.insert_space_before_comma_in_method_declaration_parameters"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to insert a space before comma in the exception names of the throws clause of a method declaration
+ * - option id: "org.eclipse.cdt.core.formatter.insert_space_before_comma_in_method_declaration_throws"
+ * - possible values: { INSERT, DO_NOT_INSERT }
+ * - default: DO_NOT_INSERT
+ * </pre>
+ * @see IDEPlugin#INSERT
+ * @see IDEPlugin#DO_NOT_INSERT
+ */
+ public static final String FORMATTER_INSERT_SPACE_BEFORE_COMMA_IN_METHOD_DECLARATION_THROWS = IDEPlugin.PLUGIN_ID + ".formatter.insert_space_before_comma_in_method_declaration_throws"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to insert a space before comma in the arguments of a method invocation
+ * - option id: "org.eclipse.cdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments"
+ * - possible values: { INSERT, DO_NOT_INSERT }
+ * - default: DO_NOT_INSERT
+ * </pre>
+ * @see IDEPlugin#INSERT
+ * @see IDEPlugin#DO_NOT_INSERT
+ */
+ public static final String FORMATTER_INSERT_SPACE_BEFORE_COMMA_IN_METHOD_INVOCATION_ARGUMENTS = IDEPlugin.PLUGIN_ID + ".formatter.insert_space_before_comma_in_method_invocation_arguments"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to insert a space before comma in a declarator list
+ * - option id: "org.eclipse.cdt.core.formatter.insert_space_before_comma_in_declarator_list"
+ * - possible values: { INSERT, DO_NOT_INSERT }
+ * - default: DO_NOT_INSERT
+ * </pre>
+ * @see IDEPlugin#INSERT
+ * @see IDEPlugin#DO_NOT_INSERT
+ */
+ public static final String FORMATTER_INSERT_SPACE_BEFORE_COMMA_IN_DECLARATOR_LIST = IDEPlugin.PLUGIN_ID + ".formatter.insert_space_before_comma_in_declarator_list"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to insert a space before comma in a expression list
+ * - option id: "org.eclipse.cdt.core.formatter.insert_space_before_comma_in_expression_list"
+ * - possible values: { INSERT, DO_NOT_INSERT }
+ * - default: DO_NOT_INSERT
+ * </pre>
+ * @see IDEPlugin#INSERT
+ * @see IDEPlugin#DO_NOT_INSERT
+ */
+ public static final String FORMATTER_INSERT_SPACE_BEFORE_COMMA_IN_EXPRESSION_LIST = IDEPlugin.PLUGIN_ID + ".formatter.insert_space_before_comma_in_expression_list"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to insert a space before comma in the base type names in a type header
+ * - option id: "org.eclipse.cdt.core.formatter.insert_space_before_comma_in_base_types"
+ * - possible values: { INSERT, DO_NOT_INSERT }
+ * - default: DO_NOT_INSERT
+ * </pre>
+ * @see IDEPlugin#INSERT
+ * @see IDEPlugin#DO_NOT_INSERT
+ */
+ public static final String FORMATTER_INSERT_SPACE_BEFORE_COMMA_IN_BASE_TYPES = IDEPlugin.PLUGIN_ID + ".formatter.insert_space_before_comma_in_base_types"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to insert a space before comma in template arguments
+ * - option id: "org.eclipse.cdt.core.formatter.insert_space_before_comma_in_template_arguments"
+ * - possible values: { INSERT, DO_NOT_INSERT }
+ * - default: DO_NOT_INSERT
+ * </pre>
+ * @see IDEPlugin#INSERT
+ * @see IDEPlugin#DO_NOT_INSERT
+ */
+ public static final String FORMATTER_INSERT_SPACE_BEFORE_COMMA_IN_TEMPLATE_ARGUMENTS = IDEPlugin.PLUGIN_ID + ".formatter.insert_space_before_comma_in_template_arguments"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to insert a space before comma in template parameters
+ * - option id: "org.eclipse.cdt.core.formatter.insert_space_before_comma_in_template_parameters"
+ * - possible values: { INSERT, DO_NOT_INSERT }
+ * - default: DO_NOT_INSERT
+ * </pre>
+ * @see IDEPlugin#INSERT
+ * @see IDEPlugin#DO_NOT_INSERT
+ */
+ public static final String FORMATTER_INSERT_SPACE_BEFORE_COMMA_IN_TEMPLATE_PARAMETERS = IDEPlugin.PLUGIN_ID + ".formatter.insert_space_before_comma_in_template_parameters"; //$NON-NLS-1$
+// /**
+// * <pre>
+// * FORMATTER / Option to insert a space before ellipsis
+// * - option id: "org.eclipse.cdt.core.formatter.insert_space_before_ellipsis"
+// * - possible values: { INSERT, DO_NOT_INSERT }
+// * - default: DO_NOT_INSERT
+// * </pre>
+// * @see IDEPlugin#INSERT
+// * @see IDEPlugin#DO_NOT_INSERT
+// */
+// public static final String FORMATTER_INSERT_SPACE_BEFORE_ELLIPSIS = IDEPlugin.PLUGIN_ID + ".formatter.insert_space_before_ellipsis"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to insert a space before the opening angle bracket in template arguments
+ * - option id: "org.eclipse.cdt.core.formatter.insert_space_before_opening_angle_bracket_in_template_arguments"
+ * - possible values: { INSERT, DO_NOT_INSERT }
+ * - default: DO_NOT_INSERT
+ * </pre>
+ * @see IDEPlugin#INSERT
+ * @see IDEPlugin#DO_NOT_INSERT
+ */
+ public static final String FORMATTER_INSERT_SPACE_BEFORE_OPENING_ANGLE_BRACKET_IN_TEMPLATE_ARGUMENTS = IDEPlugin.PLUGIN_ID + ".formatter.insert_space_before_opening_angle_bracket_in_template_arguments"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to insert a space before the opening angle bracket in template parameters
+ * - option id: "org.eclipse.cdt.core.formatter.insert_space_before_opening_angle_bracket_in_template_parameters"
+ * - possible values: { INSERT, DO_NOT_INSERT }
+ * - default: DO_NOT_INSERT
+ * </pre>
+ * @see IDEPlugin#INSERT
+ * @see IDEPlugin#DO_NOT_INSERT
+ */
+ public static final String FORMATTER_INSERT_SPACE_BEFORE_OPENING_ANGLE_BRACKET_IN_TEMPLATE_PARAMETERS = IDEPlugin.PLUGIN_ID + ".formatter.insert_space_before_opening_angle_bracket_in_template_parameters"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to insert a space before the opening brace in an initializer list
+ * - option id: "org.eclipse.cdt.core.formatter.insert_space_before_opening_brace_in_array_initializer"
+ * - possible values: { INSERT, DO_NOT_INSERT }
+ * - default: DO_NOT_INSERT
+ * </pre>
+ * @see IDEPlugin#INSERT
+ * @see IDEPlugin#DO_NOT_INSERT
+ */
+ public static final String FORMATTER_INSERT_SPACE_BEFORE_OPENING_BRACE_IN_INITIALIZER_LIST = IDEPlugin.PLUGIN_ID + ".formatter.insert_space_before_opening_brace_in_array_initializer"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to insert a space before the opening brace in a block
+ * - option id: "org.eclipse.cdt.core.formatter.insert_space_before_opening_brace_in_block"
+ * - possible values: { INSERT, DO_NOT_INSERT }
+ * - default: INSERT
+ * </pre>
+ * @see IDEPlugin#INSERT
+ * @see IDEPlugin#DO_NOT_INSERT
+ */
+ public static final String FORMATTER_INSERT_SPACE_BEFORE_OPENING_BRACE_IN_BLOCK = IDEPlugin.PLUGIN_ID + ".formatter.insert_space_before_opening_brace_in_block"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to insert a space before the opening brace in a method declaration
+ * - option id: "org.eclipse.cdt.core.formatter.insert_space_before_opening_brace_in_method_declaration"
+ * - possible values: { INSERT, DO_NOT_INSERT }
+ * - default: INSERT
+ * </pre>
+ * @see IDEPlugin#INSERT
+ * @see IDEPlugin#DO_NOT_INSERT
+ */
+ public static final String FORMATTER_INSERT_SPACE_BEFORE_OPENING_BRACE_IN_METHOD_DECLARATION = IDEPlugin.PLUGIN_ID + ".formatter.insert_space_before_opening_brace_in_method_declaration"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to insert a space before the opening brace in a switch statement
+ * - option id: "org.eclipse.cdt.core.formatter.insert_space_before_opening_brace_in_switch"
+ * - possible values: { INSERT, DO_NOT_INSERT }
+ * - default: INSERT
+ * </pre>
+ * @see IDEPlugin#INSERT
+ * @see IDEPlugin#DO_NOT_INSERT
+ */
+ public static final String FORMATTER_INSERT_SPACE_BEFORE_OPENING_BRACE_IN_SWITCH = IDEPlugin.PLUGIN_ID + ".formatter.insert_space_before_opening_brace_in_switch"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to insert a space before the opening brace in a type declaration
+ * - option id: "org.eclipse.cdt.core.formatter.insert_space_before_opening_brace_in_type_declaration"
+ * - possible values: { INSERT, DO_NOT_INSERT }
+ * - default: INSERT
+ * </pre>
+ * @see IDEPlugin#INSERT
+ * @see IDEPlugin#DO_NOT_INSERT
+ */
+ public static final String FORMATTER_INSERT_SPACE_BEFORE_OPENING_BRACE_IN_TYPE_DECLARATION = IDEPlugin.PLUGIN_ID + ".formatter.insert_space_before_opening_brace_in_type_declaration"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to insert a space before the opening brace in a namespace declaration
+ * - option id: "org.eclipse.cdt.core.formatter.insert_space_before_opening_brace_in_namespace_declaration"
+ * - possible values: { INSERT, DO_NOT_INSERT }
+ * - default: INSERT
+ * </pre>
+ * @see IDEPlugin#INSERT
+ * @see IDEPlugin#DO_NOT_INSERT
+ */
+ public static final String FORMATTER_INSERT_SPACE_BEFORE_OPENING_BRACE_IN_NAMESPACE_DECLARATION = IDEPlugin.PLUGIN_ID + ".formatter.insert_space_before_opening_brace_in_namespace_declaration"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to insert a space before the opening bracket
+ * - option id: "org.eclipse.cdt.core.formatter.insert_space_before_opening_bracket"
+ * - possible values: { INSERT, DO_NOT_INSERT }
+ * - default: DO_NOT_INSERT
+ * </pre>
+ * @see IDEPlugin#INSERT
+ * @see IDEPlugin#DO_NOT_INSERT
+ */
+ public static final String FORMATTER_INSERT_SPACE_BEFORE_OPENING_BRACKET = IDEPlugin.PLUGIN_ID + ".formatter.insert_space_before_opening_bracket";//$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to insert a space before the opening parenthesis in a catch
+ * - option id: "org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_catch"
+ * - possible values: { INSERT, DO_NOT_INSERT }
+ * - default: INSERT
+ * </pre>
+ * @see IDEPlugin#INSERT
+ * @see IDEPlugin#DO_NOT_INSERT
+ */
+ public static final String FORMATTER_INSERT_SPACE_BEFORE_OPENING_PAREN_IN_CATCH = IDEPlugin.PLUGIN_ID + ".formatter.insert_space_before_opening_paren_in_catch"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to insert a space before the opening parenthesis in a for statement
+ * - option id: "org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_for"
+ * - possible values: { INSERT, DO_NOT_INSERT }
+ * - default: INSERT
+ * </pre>
+ * @see IDEPlugin#INSERT
+ * @see IDEPlugin#DO_NOT_INSERT
+ */
+ public static final String FORMATTER_INSERT_SPACE_BEFORE_OPENING_PAREN_IN_FOR = IDEPlugin.PLUGIN_ID + ".formatter.insert_space_before_opening_paren_in_for"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to insert a space before the opening parenthesis in an if statement
+ * - option id: "org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_if"
+ * - possible values: { INSERT, DO_NOT_INSERT }
+ * - default: INSERT
+ * </pre>
+ * @see IDEPlugin#INSERT
+ * @see IDEPlugin#DO_NOT_INSERT
+ */
+ public static final String FORMATTER_INSERT_SPACE_BEFORE_OPENING_PAREN_IN_IF = IDEPlugin.PLUGIN_ID + ".formatter.insert_space_before_opening_paren_in_if"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to insert a space before the opening parenthesis in a method declaration
+ * - option id: "org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_method_declaration"
+ * - possible values: { INSERT, DO_NOT_INSERT }
+ * - default: DO_NOT_INSERT
+ * </pre>
+ * @see IDEPlugin#INSERT
+ * @see IDEPlugin#DO_NOT_INSERT
+ */
+ public static final String FORMATTER_INSERT_SPACE_BEFORE_OPENING_PAREN_IN_METHOD_DECLARATION = IDEPlugin.PLUGIN_ID + ".formatter.insert_space_before_opening_paren_in_method_declaration"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to insert a space before the opening parenthesis in a method invocation
+ * - option id: "org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_method_invocation"
+ * - possible values: { INSERT, DO_NOT_INSERT }
+ * - default: DO_NOT_INSERT
+ * </pre>
+ * @see IDEPlugin#INSERT
+ * @see IDEPlugin#DO_NOT_INSERT
+ */
+ public static final String FORMATTER_INSERT_SPACE_BEFORE_OPENING_PAREN_IN_METHOD_INVOCATION = IDEPlugin.PLUGIN_ID + ".formatter.insert_space_before_opening_paren_in_method_invocation"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to insert a space before the opening parenthesis in an exception specification
+ * - option id: "org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_exception_specification"
+ * - possible values: { INSERT, DO_NOT_INSERT }
+ * - default: DO_NOT_INSERT
+ * </pre>
+ * @see IDEPlugin#INSERT
+ * @see IDEPlugin#DO_NOT_INSERT
+ * @since 5.1
+ */
+ public static final String FORMATTER_INSERT_SPACE_BEFORE_OPENING_PAREN_IN_EXCEPTION_SPECIFICATION = IDEPlugin.PLUGIN_ID + ".formatter.insert_space_before_opening_paren_in_exception_specification"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to insert a space before the opening parenthesis in a parenthesized expression
+ * - option id: "org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression"
+ * - possible values: { INSERT, DO_NOT_INSERT }
+ * - default: INSERT
+ * </pre>
+ * @see IDEPlugin#INSERT
+ * @see IDEPlugin#DO_NOT_INSERT
+ */
+ public static final String FORMATTER_INSERT_SPACE_BEFORE_OPENING_PAREN_IN_PARENTHESIZED_EXPRESSION = IDEPlugin.PLUGIN_ID + ".formatter.insert_space_before_opening_paren_in_parenthesized_expression"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to insert a space before the opening parenthesis in a switch statement
+ * - option id: "org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_switch"
+ * - possible values: { INSERT, DO_NOT_INSERT }
+ * - default: INSERT
+ * </pre>
+ * @see IDEPlugin#INSERT
+ * @see IDEPlugin#DO_NOT_INSERT
+ */
+ public static final String FORMATTER_INSERT_SPACE_BEFORE_OPENING_PAREN_IN_SWITCH = IDEPlugin.PLUGIN_ID + ".formatter.insert_space_before_opening_paren_in_switch"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to insert a space before the opening parenthesis in a while statement
+ * - option id: "org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_while"
+ * - possible values: { INSERT, DO_NOT_INSERT }
+ * - default: INSERT
+ * </pre>
+ * @see IDEPlugin#INSERT
+ * @see IDEPlugin#DO_NOT_INSERT
+ */
+ public static final String FORMATTER_INSERT_SPACE_BEFORE_OPENING_PAREN_IN_WHILE = IDEPlugin.PLUGIN_ID + ".formatter.insert_space_before_opening_paren_in_while"; //$NON-NLS-1$
+// /**
+// * <pre>
+// * FORMATTER / Option to insert a space before parenthesized expression in return statement
+// * - option id: "org.eclipse.cdt.core.formatter.insert_space_before_parenthesized_expression_in_return"
+// * - possible values: { INSERT, DO_NOT_INSERT }
+// * - default: INSERT
+// * </pre>
+// *
+// * @see IDEPlugin#INSERT
+// * @see IDEPlugin#DO_NOT_INSERT
+// */
+// public static final String FORMATTER_INSERT_SPACE_BEFORE_PARENTHESIZED_EXPRESSION_IN_RETURN = IDEPlugin.PLUGIN_ID + ".formatter.insert_space_before_parenthesized_expression_in_return"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to insert a space before a postfix operator
+ * - option id: "org.eclipse.cdt.core.formatter.insert_space_before_postfix_operator"
+ * - possible values: { INSERT, DO_NOT_INSERT }
+ * - default: DO_NOT_INSERT
+ * </pre>
+ * @see IDEPlugin#INSERT
+ * @see IDEPlugin#DO_NOT_INSERT
+ */
+ public static final String FORMATTER_INSERT_SPACE_BEFORE_POSTFIX_OPERATOR = IDEPlugin.PLUGIN_ID + ".formatter.insert_space_before_postfix_operator"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to insert a space before a prefix operator
+ * - option id: "org.eclipse.cdt.core.formatter.insert_space_before_prefix_operator"
+ * - possible values: { INSERT, DO_NOT_INSERT }
+ * - default: DO_NOT_INSERT
+ * </pre>
+ * @see IDEPlugin#INSERT
+ * @see IDEPlugin#DO_NOT_INSERT
+ */
+ public static final String FORMATTER_INSERT_SPACE_BEFORE_PREFIX_OPERATOR = IDEPlugin.PLUGIN_ID + ".formatter.insert_space_before_prefix_operator"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to insert a space before question mark in a conditional expression
+ * - option id: "org.eclipse.cdt.core.formatter.insert_space_before_question_in_conditional"
+ * - possible values: { INSERT, DO_NOT_INSERT }
+ * - default: INSERT
+ * </pre>
+ * @see IDEPlugin#INSERT
+ * @see IDEPlugin#DO_NOT_INSERT
+ */
+ public static final String FORMATTER_INSERT_SPACE_BEFORE_QUESTION_IN_CONDITIONAL = IDEPlugin.PLUGIN_ID + ".formatter.insert_space_before_question_in_conditional"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to insert a space before semicolon
+ * - option id: "org.eclipse.cdt.core.formatter.insert_space_before_semicolon"
+ * - possible values: { INSERT, DO_NOT_INSERT }
+ * - default: DO_NOT_INSERT
+ * </pre>
+ * @see IDEPlugin#INSERT
+ * @see IDEPlugin#DO_NOT_INSERT
+ */
+ public static final String FORMATTER_INSERT_SPACE_BEFORE_SEMICOLON = IDEPlugin.PLUGIN_ID + ".formatter.insert_space_before_semicolon"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to insert a space before semicolon in for statement
+ * - option id: "org.eclipse.cdt.core.formatter.insert_space_before_semicolon_in_for"
+ * - possible values: { INSERT, DO_NOT_INSERT }
+ * - default: DO_NOT_INSERT
+ * </pre>
+ * @see IDEPlugin#INSERT
+ * @see IDEPlugin#DO_NOT_INSERT
+ */
+ public static final String FORMATTER_INSERT_SPACE_BEFORE_SEMICOLON_IN_FOR = IDEPlugin.PLUGIN_ID + ".formatter.insert_space_before_semicolon_in_for"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to insert a space before unary operator
+ * - option id: "org.eclipse.cdt.core.formatter.insert_space_before_unary_operator"
+ * - possible values: { INSERT, DO_NOT_INSERT }
+ * - default: DO_NOT_INSERT
+ * </pre>
+ * @see IDEPlugin#INSERT
+ * @see IDEPlugin#DO_NOT_INSERT
+ */
+ public static final String FORMATTER_INSERT_SPACE_BEFORE_UNARY_OPERATOR = IDEPlugin.PLUGIN_ID + ".formatter.insert_space_before_unary_operator"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to insert a space between empty braces in an initializer list
+ * - option id: "org.eclipse.cdt.core.formatter.insert_space_between_empty_braces_in_array_initializer"
+ * - possible values: { INSERT, DO_NOT_INSERT }
+ * - default: DO_NOT_INSERT
+ * </pre>
+ * @see IDEPlugin#INSERT
+ * @see IDEPlugin#DO_NOT_INSERT
+ */
+ public static final String FORMATTER_INSERT_SPACE_BETWEEN_EMPTY_BRACES_IN_INITIALIZER_LIST = IDEPlugin.PLUGIN_ID + ".formatter.insert_space_between_empty_braces_in_array_initializer"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to insert a space between empty brackets
+ * - option id: "org.eclipse.cdt.core.formatter.insert_space_between_empty_brackets"
+ * - possible values: { INSERT, DO_NOT_INSERT }
+ * - default: DO_NOT_INSERT
+ * </pre>
+ * @see IDEPlugin#INSERT
+ * @see IDEPlugin#DO_NOT_INSERT
+ */
+ public static final String FORMATTER_INSERT_SPACE_BETWEEN_EMPTY_BRACKETS = IDEPlugin.PLUGIN_ID + ".formatter.insert_space_between_empty_brackets"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to insert a space between empty parenthesis in a method declaration
+ * - option id: "org.eclipse.cdt.core.formatter.insert_space_between_empty_parens_in_method_declaration"
+ * - possible values: { INSERT, DO_NOT_INSERT }
+ * - default: DO_NOT_INSERT
+ * </pre>
+ * @see IDEPlugin#INSERT
+ * @see IDEPlugin#DO_NOT_INSERT
+ */
+ public static final String FORMATTER_INSERT_SPACE_BETWEEN_EMPTY_PARENS_IN_METHOD_DECLARATION = IDEPlugin.PLUGIN_ID + ".formatter.insert_space_between_empty_parens_in_method_declaration"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to insert a space between empty parenthesis in a method invocation
+ * - option id: "org.eclipse.cdt.core.formatter.insert_space_between_empty_parens_in_method_invocation"
+ * - possible values: { INSERT, DO_NOT_INSERT }
+ * - default: DO_NOT_INSERT
+ * </pre>
+ * @see IDEPlugin#INSERT
+ * @see IDEPlugin#DO_NOT_INSERT
+ */
+ public static final String FORMATTER_INSERT_SPACE_BETWEEN_EMPTY_PARENS_IN_METHOD_INVOCATION = IDEPlugin.PLUGIN_ID + ".formatter.insert_space_between_empty_parens_in_method_invocation"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to insert a space between empty parenthesis in an exception specification
+ * - option id: "org.eclipse.cdt.core.formatter.insert_space_between_empty_parens_in_exception_specification"
+ * - possible values: { INSERT, DO_NOT_INSERT }
+ * - default: DO_NOT_INSERT
+ * </pre>
+ * @see IDEPlugin#INSERT
+ * @see IDEPlugin#DO_NOT_INSERT
+ * @since 5.1
+ */
+ public static final String FORMATTER_INSERT_SPACE_BETWEEN_EMPTY_PARENS_IN_EXCEPTION_SPECIFICATION = IDEPlugin.PLUGIN_ID + ".formatter.insert_space_between_empty_parens_in_exception_specification"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to keep else statement on the same line
+ * - option id: "org.eclipse.cdt.core.formatter.keep_else_statement_on_same_line"
+ * - possible values: { TRUE, FALSE }
+ * - default: FALSE
+ * </pre>
+ * @see #TRUE
+ * @see #FALSE
+ */
+ public static final String FORMATTER_KEEP_ELSE_STATEMENT_ON_SAME_LINE = IDEPlugin.PLUGIN_ID + ".formatter.keep_else_statement_on_same_line"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to keep empty initializer list one one line
+ * - option id: "org.eclipse.cdt.core.formatter.keep_empty_array_initializer_on_one_line"
+ * - possible values: { TRUE, FALSE }
+ * - default: FALSE
+ * </pre>
+ * @see #TRUE
+ * @see #FALSE
+ */
+ public static final String FORMATTER_KEEP_EMPTY_INITIALIZER_LIST_ON_ONE_LINE = IDEPlugin.PLUGIN_ID + ".formatter.keep_empty_array_initializer_on_one_line"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to keep guardian clause on one line
+ * - option id: "org.eclipse.cdt.core.formatter.format_guardian_clause_on_one_line"
+ * - possible values: { TRUE, FALSE }
+ * - default: FALSE
+ * </pre>
+ * @see #TRUE
+ * @see #FALSE
+ */
+ public static final String FORMATTER_KEEP_GUARDIAN_CLAUSE_ON_ONE_LINE = IDEPlugin.PLUGIN_ID + ".formatter.format_guardian_clause_on_one_line"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to keep simple if statement on the one line
+ * - option id: "org.eclipse.cdt.core.formatter.keep_imple_if_on_one_line"
+ * - possible values: { TRUE, FALSE }
+ * - default: FALSE
+ * </pre>
+ * @see #TRUE
+ * @see #FALSE
+ */
+ public static final String FORMATTER_KEEP_SIMPLE_IF_ON_ONE_LINE = IDEPlugin.PLUGIN_ID + ".formatter.keep_imple_if_on_one_line"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to keep then statement on the same line
+ * - option id: "org.eclipse.cdt.core.formatter.keep_then_statement_on_same_line"
+ * - possible values: { TRUE, FALSE }
+ * - default: FALSE
+ * </pre>
+ * @see #TRUE
+ * @see #FALSE
+ */
+ public static final String FORMATTER_KEEP_THEN_STATEMENT_ON_SAME_LINE = IDEPlugin.PLUGIN_ID + ".formatter.keep_then_statement_on_same_line";//$NON-NLS-1$
+
+ /**
+ * <pre>
+ * FORMATTER / Option to specify the length of the page. Beyond this length, the formatter will try to split the code
+ * - option id: "org.eclipse.cdt.core.formatter.lineSplit"
+ * - possible values: "&lt;n&gt;", where n is zero or a positive integer
+ * - default: "80"
+ * </pre>
+ */
+ public static final String FORMATTER_LINE_SPLIT = IDEPlugin.PLUGIN_ID + ".formatter.lineSplit"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to specify the number of empty lines to preserve
+ * - option id: "org.eclipse.cdt.core.formatter.number_of_empty_lines_to_preserve"
+ * - possible values: "&lt;n&gt;", where n is zero or a positive integer
+ * - default: "0"
+ * </pre>
+ */
+ public static final String FORMATTER_NUMBER_OF_EMPTY_LINES_TO_PRESERVE = IDEPlugin.PLUGIN_ID + ".formatter.number_of_empty_lines_to_preserve"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to specify whether the formatter can join wrapped lines or not
+ * - option id: "org.eclipse.cdt.core.formatter.join_wrapped_lines"
+ * - possible values: { TRUE, FALSE }
+ * - default: TRUE
+ * </pre>
+ * @since 5.3
+ */
+ public static final String FORMATTER_JOIN_WRAPPED_LINES = IDEPlugin.PLUGIN_ID + ".formatter.join_wrapped_lines"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to specify whether or not empty statement should be on a new line
+ * - option id: "org.eclipse.cdt.core.formatter.put_empty_statement_on_new_line"
+ * - possible values: { TRUE, FALSE }
+ * - default: FALSE
+ * </pre>
+ * @see #TRUE
+ * @see #FALSE
+ */
+ public static final String FORMATTER_PUT_EMPTY_STATEMENT_ON_NEW_LINE = IDEPlugin.PLUGIN_ID + ".formatter.put_empty_statement_on_new_line"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to specify the tabulation size
+ * - option id: "org.eclipse.cdt.core.formatter.tabulation.char"
+ * - possible values: { TAB, SPACE, MIXED }
+ * - default: TAB
+ * </pre>
+ * More values may be added in the future.
+ *
+ * @see IDEPlugin#TAB
+ * @see IDEPlugin#SPACE
+ * @see #MIXED
+ */
+ public static final String FORMATTER_TAB_CHAR = IDEPlugin.PLUGIN_ID + ".formatter.tabulation.char"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to specify the equivalent number of spaces that represents one tabulation
+ * - option id: "org.eclipse.cdt.core.formatter.tabulation.size"
+ * - possible values: "&lt;n&gt;", where n is zero or a positive integer
+ * - default: "4"
+ * </pre>
+ */
+ public static final String FORMATTER_TAB_SIZE = IDEPlugin.PLUGIN_ID + ".formatter.tabulation.size"; //$NON-NLS-1$
+
+ /**
+ * <pre>
+ * FORMATTER / Option to use tabulations only for leading indentations
+ * - option id: "org.eclipse.cdt.core.formatter.use_tabs_only_for_leading_indentations"
+ * - possible values: { TRUE, FALSE }
+ * - default: FALSE
+ * </pre>
+ * @see #TRUE
+ * @see #FALSE
+ */
+ public static final String FORMATTER_USE_TABS_ONLY_FOR_LEADING_INDENTATIONS = IDEPlugin.PLUGIN_ID + ".formatter.use_tabs_only_for_leading_indentations"; //$NON-NLS-1$
+
+ /**
+ * <pre>
+ * FORMATTER / The wrapping is done by indenting by one compare to the current indentation.
+ * </pre>
+ */
+ public static final int INDENT_BY_ONE= 2;
+
+ /**
+ * <pre>
+ * FORMATTER / The wrapping is done by using the current indentation.
+ * </pre>
+ */
+ public static final int INDENT_DEFAULT= 0;
+ /**
+ * <pre>
+ * FORMATTER / The wrapping is done by indenting on column under the splitting location.
+ * </pre>
+ */
+ public static final int INDENT_ON_COLUMN = 1;
+
+ /**
+ * <pre>
+ * FORMATTER / Possible value for the option FORMATTER_TAB_CHAR
+ * </pre>
+ * @see IDEPlugin#TAB
+ * @see IDEPlugin#SPACE
+ * @see #FORMATTER_TAB_CHAR
+ */
+ public static final String MIXED = "mixed"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Value to set a brace location at the start of the next line with
+ * the right indentation.
+ * </pre>
+ * @see #FORMATTER_BRACE_POSITION_FOR_INITIALIZER_LIST
+ * @see #FORMATTER_BRACE_POSITION_FOR_BLOCK
+ * @see #FORMATTER_BRACE_POSITION_FOR_METHOD_DECLARATION
+ * @see #FORMATTER_BRACE_POSITION_FOR_SWITCH
+ * @see #FORMATTER_BRACE_POSITION_FOR_TYPE_DECLARATION
+ */
+ public static final String NEXT_LINE = "next_line"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Value to set a brace location at the start of the next line if a wrapping
+ * occurred.
+ * </pre>
+ * @see #FORMATTER_BRACE_POSITION_FOR_INITIALIZER_LIST
+ * @see #FORMATTER_BRACE_POSITION_FOR_BLOCK
+ * @see #FORMATTER_BRACE_POSITION_FOR_METHOD_DECLARATION
+ * @see #FORMATTER_BRACE_POSITION_FOR_SWITCH
+ * @see #FORMATTER_BRACE_POSITION_FOR_TYPE_DECLARATION
+ */
+ public static final String NEXT_LINE_ON_WRAP = "next_line_on_wrap"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Value to set a brace location at the start of the next line with
+ * an extra indentation.
+ * </pre>
+ * @see #FORMATTER_BRACE_POSITION_FOR_INITIALIZER_LIST
+ * @see #FORMATTER_BRACE_POSITION_FOR_BLOCK
+ * @see #FORMATTER_BRACE_POSITION_FOR_METHOD_DECLARATION
+ * @see #FORMATTER_BRACE_POSITION_FOR_SWITCH
+ * @see #FORMATTER_BRACE_POSITION_FOR_TYPE_DECLARATION
+ */
+ public static final String NEXT_LINE_SHIFTED = "next_line_shifted"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Value to set an option to true.
+ * </pre>
+ */
+ public static final String TRUE = "true"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / The wrapping is done using as few lines as possible.
+ * </pre>
+ */
+ public static final int WRAP_COMPACT= 1;
+ /**
+ * <pre>
+ * FORMATTER / The wrapping is done putting the first element on a new
+ * line and then wrapping next elements using as few lines as possible.
+ * </pre>
+ */
+ public static final int WRAP_COMPACT_FIRST_BREAK= 2;
+ /**
+ * <pre>
+ * FORMATTER / The wrapping is done by putting each element on its own line
+ * except the first element.
+ * </pre>
+ */
+ public static final int WRAP_NEXT_PER_LINE= 5;
+ /**
+ * <pre>
+ * FORMATTER / The wrapping is done by putting each element on its own line.
+ * All elements are indented by one except the first element.
+ * </pre>
+ */
+ public static final int WRAP_NEXT_SHIFTED= 4;
+
+ /**
+ * <pre>
+ * FORMATTER / Value to disable alignment.
+ * </pre>
+ */
+ public static final int WRAP_NO_SPLIT= 0;
+ /**
+ * <pre>
+ * FORMATTER / The wrapping is done by putting each element on its own line.
+ * </pre>
+ */
+ public static final int WRAP_ONE_PER_LINE= 3;
+
+ /*
+ * Private constants.
+ */
+ private static final IllegalArgumentException WRONG_ARGUMENT = new IllegalArgumentException();
+
+ /**
+ * Create a new alignment value according to the given values. This must be used to set up
+ * the alignment options.
+ *
+ * @param forceSplit the given force value
+ * @param wrapStyle the given wrapping style
+ * @param indentStyle the given indent style
+ *
+ * @return the new alignment value
+ */
+ public static String createAlignmentValue(boolean forceSplit, int wrapStyle, int indentStyle) {
+ int alignmentValue = 0;
+ switch (wrapStyle) {
+ case WRAP_COMPACT:
+ alignmentValue |= STPAlignment.M_COMPACT_SPLIT;
+ break;
+ case WRAP_COMPACT_FIRST_BREAK:
+ alignmentValue |= STPAlignment.M_COMPACT_FIRST_BREAK_SPLIT;
+ break;
+ case WRAP_NEXT_PER_LINE:
+ alignmentValue |= STPAlignment.M_NEXT_PER_LINE_SPLIT;
+ break;
+ case WRAP_NEXT_SHIFTED:
+ alignmentValue |= STPAlignment.M_NEXT_SHIFTED_SPLIT;
+ break;
+ case WRAP_ONE_PER_LINE:
+ alignmentValue |= STPAlignment.M_ONE_PER_LINE_SPLIT;
+ break;
+ }
+ if (forceSplit) {
+ alignmentValue |= STPAlignment.M_FORCE;
+ }
+ switch (indentStyle) {
+ case INDENT_BY_ONE:
+ alignmentValue |= STPAlignment.M_INDENT_BY_ONE;
+ break;
+ case INDENT_ON_COLUMN:
+ alignmentValue |= STPAlignment.M_INDENT_ON_COLUMN;
+ }
+ return String.valueOf(alignmentValue);
+ }
+
+ /**
+ * Returns the default formatter settings
+ *
+ * @return the default settings
+ */
+ public static Map<String,String> getDefaultSettings() {
+ return STPDefaultCodeFormatterOptions.getDefaultSettings().getMap();
+ }
+
+ /**
+ * Returns the K&R formatter settings
+ *
+ * @return the K&R settings
+ */
+ public static Map<String,String> getKandRSettings() {
+ return STPDefaultCodeFormatterOptions.getKandRSettings().getMap();
+ }
+
+ /**
+ * Returns the Allman formatter settings
+ *
+ * @return the Allman settings
+ */
+ public static Map<String,String> getAllmanSettings() {
+ return STPDefaultCodeFormatterOptions.getAllmanSettings().getMap();
+ }
+
+ /**
+ * Returns the GNU formatter settings
+ *
+ * @return the GNU settings
+ */
+ public static Map<String,String> getGNUSettings() {
+ return STPDefaultCodeFormatterOptions.getGNUSettings().getMap();
+ }
+
+ /**
+ * Returns the Whitesmiths formatter settings
+ *
+ * @return the Whitesmiths settings
+ */
+ public static Map<String,String> getWhitesmithsSettings() {
+ return STPDefaultCodeFormatterOptions.getWhitesmithsSettings().getMap();
+ }
+
+ /**
+ * <p>Return the force value of the given alignment value.
+ * The given alignment value should be created using the <code>createAlignmentValue(boolean, int, int)</code>
+ * API.
+ * </p>
+ *
+ * @param value the given alignment value
+ * @return the force value of the given alignment value
+ * @see #createAlignmentValue(boolean, int, int)
+ * @exception IllegalArgumentException if the given alignment value is null, or if it
+ * doesn't have a valid format.
+ */
+ public static boolean getForceWrapping(String value) {
+ if (value == null) {
+ throw WRONG_ARGUMENT;
+ }
+ try {
+ int existingValue = Integer.parseInt(value);
+ return (existingValue & STPAlignment.M_FORCE) != 0;
+ } catch (NumberFormatException e) {
+ throw WRONG_ARGUMENT;
+ }
+ }
+
+ /**
+ * <p>Return the indentation style of the given alignment value.
+ * The given alignment value should be created using the <code>createAlignmentValue(boolean, int, int)</code>
+ * API.
+ * </p>
+ *
+ * @param value the given alignment value
+ * @return the indentation style of the given alignment value
+ * @see #createAlignmentValue(boolean, int, int)
+ * @exception IllegalArgumentException if the given alignment value is null, or if it
+ * doesn't have a valid format.
+ */
+ public static int getIndentStyle(String value) {
+ if (value == null) {
+ throw WRONG_ARGUMENT;
+ }
+ try {
+ int existingValue = Integer.parseInt(value);
+ if ((existingValue & STPAlignment.M_INDENT_BY_ONE) != 0) {
+ return INDENT_BY_ONE;
+ } else if ((existingValue & STPAlignment.M_INDENT_ON_COLUMN) != 0) {
+ return INDENT_ON_COLUMN;
+ } else {
+ return INDENT_DEFAULT;
+ }
+ } catch (NumberFormatException e) {
+ throw WRONG_ARGUMENT;
+ }
+ }
+
+ /**
+ * <p>Return the wrapping style of the given alignment value.
+ * The given alignment value should be created using the <code>createAlignmentValue(boolean, int, int)</code>
+ * API.
+ * </p>
+ *
+ * @param value the given alignment value
+ * @return the wrapping style of the given alignment value
+ * @see #createAlignmentValue(boolean, int, int)
+ * @exception IllegalArgumentException if the given alignment value is null, or if it
+ * doesn't have a valid format.
+ */
+ public static int getWrappingStyle(String value) {
+ if (value == null) {
+ throw WRONG_ARGUMENT;
+ }
+ try {
+ int existingValue = Integer.parseInt(value) & STPAlignment.SPLIT_MASK;
+ switch (existingValue) {
+ case STPAlignment.M_COMPACT_SPLIT:
+ return WRAP_COMPACT;
+ case STPAlignment.M_COMPACT_FIRST_BREAK_SPLIT:
+ return WRAP_COMPACT_FIRST_BREAK;
+ case STPAlignment.M_NEXT_PER_LINE_SPLIT:
+ return WRAP_NEXT_PER_LINE;
+ case STPAlignment.M_NEXT_SHIFTED_SPLIT:
+ return WRAP_NEXT_SHIFTED;
+ case STPAlignment.M_ONE_PER_LINE_SPLIT:
+ return WRAP_ONE_PER_LINE;
+ default:
+ return WRAP_NO_SPLIT;
+ }
+ } catch (NumberFormatException e) {
+ throw WRONG_ARGUMENT;
+ }
+ }
+ /**
+ * <p>Set the force value of the given alignment value and return the new value.
+ * The given alignment value should be created using the <code>createAlignmentValue(boolean, int, int)</code>
+ * API.
+ * </p>
+ *
+ * @param value the given alignment value
+ * @param force the given force value
+ * @return the new alignment value
+ * @see #createAlignmentValue(boolean, int, int)
+ * @exception IllegalArgumentException if the given alignment value is null, or if it
+ * doesn't have a valid format.
+ */
+ public static String setForceWrapping(String value, boolean force) {
+ if (value == null) {
+ throw WRONG_ARGUMENT;
+ }
+ try {
+ int existingValue = Integer.parseInt(value);
+ // clear existing force bit
+ existingValue &= ~STPAlignment.M_FORCE;
+ if (force) {
+ existingValue |= STPAlignment.M_FORCE;
+ }
+ return String.valueOf(existingValue);
+ } catch (NumberFormatException e) {
+ throw WRONG_ARGUMENT;
+ }
+ }
+
+ /**
+ * <p>Set the indentation style of the given alignment value and return the new value.
+ * The given value should be created using the <code>createAlignmentValue(boolean, int, int)</code>
+ * API.
+ * </p>
+ *
+ * @param value the given alignment value
+ * @param indentStyle the given indentation style
+ * @return the new alignment value
+ * @see #INDENT_BY_ONE
+ * @see #INDENT_DEFAULT
+ * @see #INDENT_ON_COLUMN
+ * @see #createAlignmentValue(boolean, int, int)
+ * @exception IllegalArgumentException if the given alignment value is null, if the given
+ * indentation style is not one of the possible indentation styles, or if the given
+ * alignment value doesn't have a valid format.
+ */
+ public static String setIndentStyle(String value, int indentStyle) {
+ if (value == null) {
+ throw WRONG_ARGUMENT;
+ }
+ switch(indentStyle) {
+ case INDENT_BY_ONE:
+ case INDENT_DEFAULT:
+ case INDENT_ON_COLUMN:
+ break;
+ default:
+ throw WRONG_ARGUMENT;
+ }
+ try {
+ int existingValue = Integer.parseInt(value);
+ // clear existing indent bits
+ existingValue &= ~(STPAlignment.M_INDENT_BY_ONE | STPAlignment.M_INDENT_ON_COLUMN);
+ switch(indentStyle) {
+ case INDENT_BY_ONE:
+ existingValue |= STPAlignment.M_INDENT_BY_ONE;
+ break;
+ case INDENT_ON_COLUMN:
+ existingValue |= STPAlignment.M_INDENT_ON_COLUMN;
+ }
+ return String.valueOf(existingValue);
+ } catch (NumberFormatException e) {
+ throw WRONG_ARGUMENT;
+ }
+ }
+ /**
+ * <p>Set the wrapping style of the given alignment value and return the new value.
+ * The given value should be created using the <code>createAlignmentValue(boolean, int, int)</code>
+ * API.
+ * </p>
+ *
+ * @param value the given alignment value
+ * @param wrappingStyle the given wrapping style
+ * @return the new alignment value
+ * @see #WRAP_COMPACT
+ * @see #WRAP_COMPACT_FIRST_BREAK
+ * @see #WRAP_NEXT_PER_LINE
+ * @see #WRAP_NEXT_SHIFTED
+ * @see #WRAP_NO_SPLIT
+ * @see #WRAP_ONE_PER_LINE
+ * @see #createAlignmentValue(boolean, int, int)
+ * @exception IllegalArgumentException if the given alignment value is null, if the given
+ * wrapping style is not one of the possible wrapping styles, or if the given
+ * alignment value doesn't have a valid format.
+ */
+ public static String setWrappingStyle(String value, int wrappingStyle) {
+ if (value == null) {
+ throw WRONG_ARGUMENT;
+ }
+ switch (wrappingStyle) {
+ case WRAP_COMPACT:
+ case WRAP_COMPACT_FIRST_BREAK:
+ case WRAP_NEXT_PER_LINE:
+ case WRAP_NEXT_SHIFTED:
+ case WRAP_NO_SPLIT:
+ case WRAP_ONE_PER_LINE:
+ break;
+ default:
+ throw WRONG_ARGUMENT;
+ }
+ try {
+ int existingValue = Integer.parseInt(value);
+ // clear existing split bits
+ existingValue &= ~(STPAlignment.SPLIT_MASK);
+ switch (wrappingStyle) {
+ case WRAP_COMPACT:
+ existingValue |= STPAlignment.M_COMPACT_SPLIT;
+ break;
+ case WRAP_COMPACT_FIRST_BREAK:
+ existingValue |= STPAlignment.M_COMPACT_FIRST_BREAK_SPLIT;
+ break;
+ case WRAP_NEXT_PER_LINE:
+ existingValue |= STPAlignment.M_NEXT_PER_LINE_SPLIT;
+ break;
+ case WRAP_NEXT_SHIFTED:
+ existingValue |= STPAlignment.M_NEXT_SHIFTED_SPLIT;
+ break;
+ case WRAP_ONE_PER_LINE:
+ existingValue |= STPAlignment.M_ONE_PER_LINE_SPLIT;
+ break;
+ }
+ return String.valueOf(existingValue);
+ } catch (NumberFormatException e) {
+ throw WRONG_ARGUMENT;
+ }
+ }
+}
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPDefaultCodeFormatterOptions.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPDefaultCodeFormatterOptions.java
new file mode 100644
index 0000000000..745a95e4ce
--- /dev/null
+++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPDefaultCodeFormatterOptions.java
@@ -0,0 +1,1912 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2012, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ * Sergey Prigogin (Google)
+ * Anton Leherbauer (Wind River Systems)
+ * Red Hat Inc. - modified for use in SystemTap
+ *******************************************************************************/
+package org.eclipse.linuxtools.internal.systemtap.ui.ide.editors.stp;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.linuxtools.internal.systemtap.ui.ide.IDEPlugin;
+
+/**
+ * Code formatter options.
+ *
+ * @noextend This class is not intended to be subclassed by clients.
+ * @since 5.4
+ */
+public class STPDefaultCodeFormatterOptions {
+ public static final int TAB = 1;
+ public static final int SPACE = 2;
+ public static final int MIXED = 4;
+
+ public static STPDefaultCodeFormatterOptions getDefaultSettings() {
+ STPDefaultCodeFormatterOptions options = new STPDefaultCodeFormatterOptions();
+ options.setDefaultSettings();
+ return options;
+ }
+
+ public static STPDefaultCodeFormatterOptions getKandRSettings() {
+ STPDefaultCodeFormatterOptions options = new STPDefaultCodeFormatterOptions();
+ options.setKandRSettings();
+ return options;
+ }
+
+ public static STPDefaultCodeFormatterOptions getAllmanSettings() {
+ STPDefaultCodeFormatterOptions options = new STPDefaultCodeFormatterOptions();
+ options.setAllmanSettings();
+ return options;
+ }
+
+ public static STPDefaultCodeFormatterOptions getGNUSettings() {
+ STPDefaultCodeFormatterOptions options = new STPDefaultCodeFormatterOptions();
+ options.setGNUSettings();
+ return options;
+ }
+
+ public static STPDefaultCodeFormatterOptions getWhitesmithsSettings() {
+ STPDefaultCodeFormatterOptions options = new STPDefaultCodeFormatterOptions();
+ options.setWhitesmitsSettings();
+ return options;
+ }
+
+ public int alignment_for_arguments_in_method_invocation;
+ public int alignment_for_assignment;
+ public int alignment_for_base_clause_in_type_declaration;
+ public int alignment_for_binary_expression;
+ public int alignment_for_compact_if;
+ public int alignment_for_conditional_expression_chain;
+ public int alignment_for_conditional_expression;
+ public int alignment_for_declarator_list;
+ public int alignment_for_enumerator_list;
+ public int alignment_for_expression_list;
+ public int alignment_for_expressions_in_initializer_list;
+ public int alignment_for_member_access;
+ public int alignment_for_overloaded_left_shift_chain;
+ public int alignment_for_parameters_in_method_declaration;
+ public int alignment_for_throws_clause_in_method_declaration;
+ public int alignment_for_constructor_initializer_list;
+
+// public boolean align_type_members_on_columns;
+
+ public String brace_position_for_block;
+ public String brace_position_for_block_in_case;
+// public String brace_position_for_enum_declaration;
+ public String brace_position_for_initializer_list;
+ public String brace_position_for_method_declaration;
+ public String brace_position_for_namespace_declaration;
+ public String brace_position_for_switch;
+ public String brace_position_for_type_declaration;
+
+// public int blank_lines_after_includes;
+// public int blank_lines_at_beginning_of_method_body;
+// public int blank_lines_before_field;
+// public int blank_lines_before_first_class_body_declaration;
+// public int blank_lines_before_includes;
+// public int blank_lines_before_member_type;
+// public int blank_lines_before_method;
+// public int blank_lines_before_new_chunk;
+// public int blank_lines_between_type_declarations;
+
+// public boolean comment_clear_blank_lines;
+// public boolean comment_format;
+// public boolean comment_format_header;
+// public boolean comment_format_html;
+// public boolean comment_format_source;
+// public int comment_line_length;
+ public int comment_min_distance_between_code_and_line_comment;
+ public boolean comment_preserve_white_space_between_code_and_line_comment;
+ public boolean never_indent_line_comments_on_first_column;
+
+ public int continuation_indentation;
+ public int continuation_indentation_for_initializer_list;
+
+ public boolean indent_statements_compare_to_block;
+ public boolean indent_statements_compare_to_body;
+ public boolean indent_body_declarations_compare_to_access_specifier;
+ public boolean indent_access_specifier_compare_to_type_header;
+ public int indent_access_specifier_extra_spaces;
+ public boolean indent_body_declarations_compare_to_namespace_header;
+ public boolean indent_declaration_compare_to_template_header;
+ public boolean indent_breaks_compare_to_cases;
+ public boolean indent_empty_lines;
+ public boolean indent_switchstatements_compare_to_cases;
+ public boolean indent_switchstatements_compare_to_switch;
+ public int indentation_size;
+
+ public boolean insert_new_line_after_opening_brace_in_initializer_list;
+ public boolean insert_new_line_after_template_declaration;
+ public boolean insert_new_line_at_end_of_file_if_missing;
+ public boolean insert_new_line_before_catch_in_try_statement;
+ public boolean insert_new_line_before_closing_brace_in_initializer_list;
+ public boolean insert_new_line_before_colon_in_constructor_initializer_list;
+ public boolean insert_new_line_before_else_in_if_statement;
+ public boolean insert_new_line_before_while_in_do_statement;
+ public boolean insert_new_line_before_identifier_in_function_declaration;
+ public boolean insert_new_line_in_empty_block;
+// public boolean insert_new_line_in_empty_method_body;
+// public boolean insert_new_line_in_empty_type_declaration;
+ public boolean insert_space_after_assignment_operator;
+ public boolean insert_space_after_binary_operator;
+ public boolean insert_space_after_closing_angle_bracket_in_template_arguments;
+ public boolean insert_space_after_closing_angle_bracket_in_template_parameters;
+ public boolean insert_space_after_closing_paren_in_cast;
+ public boolean insert_space_after_closing_brace_in_block;
+ public boolean insert_space_after_colon_in_base_clause;
+ public boolean insert_space_after_colon_in_case;
+ public boolean insert_space_after_colon_in_conditional;
+ public boolean insert_space_after_colon_in_labeled_statement;
+// public boolean insert_space_after_comma_in_allocation_expression;
+ public boolean insert_space_after_comma_in_initializer_list;
+ public boolean insert_space_after_comma_in_enum_declarations;
+// public boolean insert_space_after_comma_in_for_increments;
+// public boolean insert_space_after_comma_in_for_inits;
+ public boolean insert_space_after_comma_in_method_invocation_arguments;
+ public boolean insert_space_after_comma_in_method_declaration_parameters;
+ public boolean insert_space_after_comma_in_method_declaration_throws;
+ public boolean insert_space_after_comma_in_declarator_list;
+ public boolean insert_space_after_comma_in_expression_list;
+ public boolean insert_space_after_comma_in_base_types;
+ public boolean insert_space_after_comma_in_template_arguments;
+ public boolean insert_space_after_comma_in_template_parameters;
+// public boolean insert_space_after_ellipsis;
+ public boolean insert_space_after_opening_angle_bracket_in_template_arguments;
+ public boolean insert_space_after_opening_angle_bracket_in_template_parameters;
+ public boolean insert_space_after_opening_bracket;
+ public boolean insert_space_after_opening_brace_in_initializer_list;
+ public boolean insert_space_after_opening_paren_in_cast;
+ public boolean insert_space_after_opening_paren_in_catch;
+ public boolean insert_space_after_opening_paren_in_for;
+ public boolean insert_space_after_opening_paren_in_if;
+ public boolean insert_space_after_opening_paren_in_method_declaration;
+ public boolean insert_space_after_opening_paren_in_method_invocation;
+ public boolean insert_space_after_opening_paren_in_exception_specification;
+ public boolean insert_space_after_opening_paren_in_parenthesized_expression;
+ public boolean insert_space_after_opening_paren_in_switch;
+ public boolean insert_space_after_opening_paren_in_while;
+ public boolean insert_space_after_postfix_operator;
+ public boolean insert_space_after_prefix_operator;
+ public boolean insert_space_after_question_in_conditional;
+ public boolean insert_space_after_semicolon_in_for;
+ public boolean insert_space_after_unary_operator;
+ public boolean insert_space_before_assignment_operator;
+ public boolean insert_space_before_binary_operator;
+ public boolean insert_space_before_closing_angle_bracket_in_template_arguments;
+ public boolean insert_space_before_closing_angle_bracket_in_template_parameters;
+ public boolean insert_space_before_closing_brace_in_initializer_list;
+ public boolean insert_space_before_closing_bracket;
+ public boolean insert_space_before_closing_paren_in_cast;
+ public boolean insert_space_before_closing_paren_in_catch;
+ public boolean insert_space_before_closing_paren_in_for;
+ public boolean insert_space_before_closing_paren_in_if;
+ public boolean insert_space_before_closing_paren_in_method_declaration;
+ public boolean insert_space_before_closing_paren_in_method_invocation;
+ public boolean insert_space_before_closing_paren_in_exception_specification;
+ public boolean insert_space_before_closing_paren_in_parenthesized_expression;
+ public boolean insert_space_before_closing_paren_in_switch;
+ public boolean insert_space_before_closing_paren_in_while;
+ public boolean insert_space_before_colon_in_base_clause;
+ public boolean insert_space_before_colon_in_case;
+ public boolean insert_space_before_colon_in_conditional;
+ public boolean insert_space_before_colon_in_default;
+ public boolean insert_space_before_colon_in_labeled_statement;
+// public boolean insert_space_before_comma_in_allocation_expression;
+ public boolean insert_space_before_comma_in_initializer_list;
+ public boolean insert_space_before_comma_in_enum_declarations;
+// public boolean insert_space_before_comma_in_for_increments;
+// public boolean insert_space_before_comma_in_for_inits;
+ public boolean insert_space_before_comma_in_method_invocation_arguments;
+ public boolean insert_space_before_comma_in_method_declaration_parameters;
+ public boolean insert_space_before_comma_in_method_declaration_throws;
+ public boolean insert_space_before_comma_in_declarator_list;
+ public boolean insert_space_before_comma_in_expression_list;
+ public boolean insert_space_before_comma_in_base_types;
+ public boolean insert_space_before_comma_in_template_arguments;
+ public boolean insert_space_before_comma_in_template_parameters;
+// public boolean insert_space_before_ellipsis;
+// public boolean insert_space_before_parenthesized_expression_in_return;
+ public boolean insert_space_before_opening_angle_bracket_in_template_arguments;
+ public boolean insert_space_before_opening_angle_bracket_in_template_parameters;
+ public boolean insert_space_before_opening_brace_in_initializer_list;
+ public boolean insert_space_before_opening_brace_in_block;
+ public boolean insert_space_before_opening_brace_in_method_declaration;
+ public boolean insert_space_before_opening_brace_in_type_declaration;
+ public boolean insert_space_before_opening_brace_in_namespace_declaration;
+ public boolean insert_space_before_opening_bracket;
+ public boolean insert_space_before_opening_paren_in_catch;
+ public boolean insert_space_before_opening_paren_in_for;
+ public boolean insert_space_before_opening_paren_in_if;
+ public boolean insert_space_before_opening_paren_in_method_invocation;
+ public boolean insert_space_before_opening_paren_in_exception_specification;
+ public boolean insert_space_before_opening_paren_in_method_declaration;
+ public boolean insert_space_before_opening_paren_in_switch;
+ public boolean insert_space_before_opening_brace_in_switch;
+ public boolean insert_space_before_opening_paren_in_parenthesized_expression;
+ public boolean insert_space_before_opening_paren_in_while;
+ public boolean insert_space_before_postfix_operator;
+ public boolean insert_space_before_prefix_operator;
+ public boolean insert_space_before_question_in_conditional;
+ public boolean insert_space_before_semicolon;
+ public boolean insert_space_before_semicolon_in_for;
+ public boolean insert_space_before_unary_operator;
+ public boolean insert_space_between_empty_braces_in_initializer_list;
+ public boolean insert_space_between_empty_brackets;
+ public boolean insert_space_between_empty_parens_in_method_declaration;
+ public boolean insert_space_between_empty_parens_in_method_invocation;
+ public boolean insert_space_between_empty_parens_in_exception_specification;
+ public boolean compact_else_if;
+ public boolean keep_guardian_clause_on_one_line;
+ public boolean keep_else_statement_on_same_line;
+ public boolean keep_empty_initializer_list_on_one_line;
+ public boolean keep_simple_if_on_one_line;
+ public boolean keep_then_statement_on_same_line;
+ public int number_of_empty_lines_to_preserve;
+ public boolean join_wrapped_lines;
+ public boolean put_empty_statement_on_new_line;
+ public int tab_size;
+ public int page_width;
+ public int tab_char = TAB;
+ public boolean use_tabs_only_for_leading_indentations;
+ public int initial_indentation_level;
+ public String line_separator;
+
+ private STPDefaultCodeFormatterOptions() {
+ // cannot be instantiated
+ }
+
+ public STPDefaultCodeFormatterOptions(Map<String, String> settings) {
+ setDefaultSettings();
+ if (settings == null) return;
+ set(settings);
+ }
+
+ private String getAlignment(int alignment) {
+ return Integer.toString(alignment);
+ }
+
+ public Map<String, String> getMap() {
+ Map<String, String> options = new HashMap<String, String>();
+// options.put(STPDefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_ARGUMENTS_IN_ALLOCATION_EXPRESSION, getAlignment(this.alignment_for_arguments_in_allocation_expression));
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_ARGUMENTS_IN_METHOD_INVOCATION, getAlignment(this.alignment_for_arguments_in_method_invocation));
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_ASSIGNMENT, getAlignment(this.alignment_for_assignment));
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_BINARY_EXPRESSION, getAlignment(this.alignment_for_binary_expression));
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_COMPACT_IF, getAlignment(this.alignment_for_compact_if));
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_CONDITIONAL_EXPRESSION, getAlignment(this.alignment_for_conditional_expression));
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_CONDITIONAL_EXPRESSION_CHAIN, getAlignment(this.alignment_for_conditional_expression_chain));
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_DECLARATOR_LIST, getAlignment(this.alignment_for_declarator_list));
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_ENUMERATOR_LIST, getAlignment(this.alignment_for_enumerator_list));
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_EXPRESSIONS_IN_INITIALIZER_LIST, getAlignment(this.alignment_for_expressions_in_initializer_list));
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_EXPRESSION_LIST, getAlignment(this.alignment_for_expression_list));
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_MEMBER_ACCESS, getAlignment(this.alignment_for_member_access));
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_OVERLOADED_LEFT_SHIFT_CHAIN, getAlignment(this.alignment_for_overloaded_left_shift_chain));
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_PARAMETERS_IN_METHOD_DECLARATION, getAlignment(this.alignment_for_parameters_in_method_declaration));
+// options.put(STPDefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_SELECTOR_IN_METHOD_INVOCATION, getAlignment(this.alignment_for_selector_in_method_invocation));
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_BASE_CLAUSE_IN_TYPE_DECLARATION, getAlignment(this.alignment_for_base_clause_in_type_declaration));
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_CONSTRUCTOR_INITIALIZER_LIST, getAlignment(this.alignment_for_constructor_initializer_list));
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_THROWS_CLAUSE_IN_METHOD_DECLARATION, getAlignment(this.alignment_for_throws_clause_in_method_declaration));
+// options.put(STPDefaultCodeFormatterConstants.FORMATTER_ALIGN_TYPE_MEMBERS_ON_COLUMNS, this.align_type_members_on_columns ? STPDefaultCodeFormatterConstants.TRUE : STPDefaultCodeFormatterConstants.FALSE);
+// options.put(STPDefaultCodeFormatterConstants.FORMATTER_BLANK_LINES_AFTER_IMPORTS, Integer.toString(this.blank_lines_after_includes));
+// options.put(STPDefaultCodeFormatterConstants.FORMATTER_BLANK_LINES_BEFORE_FIELD, Integer.toString(this.blank_lines_before_field));
+// options.put(STPDefaultCodeFormatterConstants.FORMATTER_BLANK_LINES_BEFORE_FIRST_CLASS_BODY_DECLARATION, Integer.toString(this.blank_lines_before_first_class_body_declaration));
+// options.put(STPDefaultCodeFormatterConstants.FORMATTER_BLANK_LINES_BEFORE_IMPORTS, Integer.toString(this.blank_lines_before_includes));
+// options.put(STPDefaultCodeFormatterConstants.FORMATTER_BLANK_LINES_BEFORE_MEMBER_TYPE, Integer.toString(this.blank_lines_before_member_type));
+// options.put(STPDefaultCodeFormatterConstants.FORMATTER_BLANK_LINES_BEFORE_METHOD, Integer.toString(this.blank_lines_before_method));
+// options.put(STPDefaultCodeFormatterConstants.FORMATTER_BLANK_LINES_BEFORE_NEW_CHUNK, Integer.toString(this.blank_lines_before_new_chunk));
+// options.put(STPDefaultCodeFormatterConstants.FORMATTER_BLANK_LINES_BETWEEN_TYPE_DECLARATIONS, Integer.toString(this.blank_lines_between_type_declarations));
+// options.put(STPDefaultCodeFormatterConstants.FORMATTER_BLANK_LINES_AT_BEGINNING_OF_METHOD_BODY, Integer.toString(this.blank_lines_at_beginning_of_method_body));
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_BRACE_POSITION_FOR_INITIALIZER_LIST, this.brace_position_for_initializer_list);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_BRACE_POSITION_FOR_BLOCK, this.brace_position_for_block);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_BRACE_POSITION_FOR_BLOCK_IN_CASE, this.brace_position_for_block_in_case);
+// options.put(STPDefaultCodeFormatterConstants.FORMATTER_BRACE_POSITION_FOR_ENUM_DECLARATION, this.brace_position_for_enum_declaration);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_BRACE_POSITION_FOR_METHOD_DECLARATION, this.brace_position_for_method_declaration);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_BRACE_POSITION_FOR_TYPE_DECLARATION, this.brace_position_for_type_declaration);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_BRACE_POSITION_FOR_SWITCH, this.brace_position_for_switch);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_BRACE_POSITION_FOR_NAMESPACE_DECLARATION, this.brace_position_for_namespace_declaration);
+// options.put(STPDefaultCodeFormatterConstants.FORMATTER_COMMENT_CLEAR_BLANK_LINES, this.comment_clear_blank_lines ? STPDefaultCodeFormatterConstants.TRUE : STPDefaultCodeFormatterConstants.FALSE);
+// options.put(STPDefaultCodeFormatterConstants.FORMATTER_COMMENT_FORMAT, this.comment_format ? STPDefaultCodeFormatterConstants.TRUE : STPDefaultCodeFormatterConstants.FALSE);
+// options.put(STPDefaultCodeFormatterConstants.FORMATTER_COMMENT_FORMAT_HEADER, this.comment_format_header ? STPDefaultCodeFormatterConstants.TRUE : STPDefaultCodeFormatterConstants.FALSE);
+// options.put(STPDefaultCodeFormatterConstants.FORMATTER_COMMENT_FORMAT_HTML, this.comment_format_html ? STPDefaultCodeFormatterConstants.TRUE : STPDefaultCodeFormatterConstants.FALSE);
+// options.put(STPDefaultCodeFormatterConstants.FORMATTER_COMMENT_FORMAT_SOURCE, this.comment_format_source ? STPDefaultCodeFormatterConstants.TRUE : STPDefaultCodeFormatterConstants.FALSE);
+// options.put(STPDefaultCodeFormatterConstants.FORMATTER_COMMENT_LINE_LENGTH, Integer.toString(this.comment_line_length));
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_COMMENT_MIN_DISTANCE_BETWEEN_CODE_AND_LINE_COMMENT, Integer.toString(this.comment_min_distance_between_code_and_line_comment));
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_COMMENT_PRESERVE_WHITE_SPACE_BETWEEN_CODE_AND_LINE_COMMENT, this.comment_preserve_white_space_between_code_and_line_comment ? STPDefaultCodeFormatterConstants.TRUE : STPDefaultCodeFormatterConstants.FALSE);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_COMMENT_NEVER_INDENT_LINE_COMMENTS_ON_FIRST_COLUMN, this.never_indent_line_comments_on_first_column ? STPDefaultCodeFormatterConstants.TRUE : STPDefaultCodeFormatterConstants.FALSE);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_CONTINUATION_INDENTATION, Integer.toString(this.continuation_indentation));
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_CONTINUATION_INDENTATION_FOR_INITIALIZER_LIST, Integer.toString(this.continuation_indentation_for_initializer_list));
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_INDENT_STATEMENTS_COMPARE_TO_BLOCK, this.indent_statements_compare_to_block ? STPDefaultCodeFormatterConstants.TRUE : STPDefaultCodeFormatterConstants.FALSE);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_INDENT_STATEMENTS_COMPARE_TO_BODY, this.indent_statements_compare_to_body ? STPDefaultCodeFormatterConstants.TRUE : STPDefaultCodeFormatterConstants.FALSE);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_INDENT_BODY_DECLARATIONS_COMPARE_TO_ACCESS_SPECIFIER, this.indent_body_declarations_compare_to_access_specifier ? STPDefaultCodeFormatterConstants.TRUE : STPDefaultCodeFormatterConstants.FALSE);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_INDENT_ACCESS_SPECIFIER_COMPARE_TO_TYPE_HEADER, this.indent_access_specifier_compare_to_type_header ? STPDefaultCodeFormatterConstants.TRUE : STPDefaultCodeFormatterConstants.FALSE);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_INDENT_ACCESS_SPECIFIER_EXTRA_SPACES, String.valueOf(this.indent_access_specifier_extra_spaces));
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_INDENT_DECLARATION_COMPARE_TO_TEMPLATE_HEADER, this.indent_declaration_compare_to_template_header? STPDefaultCodeFormatterConstants.TRUE : STPDefaultCodeFormatterConstants.FALSE);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_INDENT_BODY_DECLARATIONS_COMPARE_TO_NAMESPACE_HEADER, this.indent_body_declarations_compare_to_namespace_header ? STPDefaultCodeFormatterConstants.TRUE : STPDefaultCodeFormatterConstants.FALSE);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_INDENT_BREAKS_COMPARE_TO_CASES, this.indent_breaks_compare_to_cases ? STPDefaultCodeFormatterConstants.TRUE : STPDefaultCodeFormatterConstants.FALSE);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_INDENT_EMPTY_LINES, this.indent_empty_lines ? STPDefaultCodeFormatterConstants.TRUE : STPDefaultCodeFormatterConstants.FALSE);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_INDENT_SWITCHSTATEMENTS_COMPARE_TO_CASES, this.indent_switchstatements_compare_to_cases ? STPDefaultCodeFormatterConstants.TRUE : STPDefaultCodeFormatterConstants.FALSE);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_INDENT_SWITCHSTATEMENTS_COMPARE_TO_SWITCH, this.indent_switchstatements_compare_to_switch ? STPDefaultCodeFormatterConstants.TRUE : STPDefaultCodeFormatterConstants.FALSE);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_INDENTATION_SIZE, Integer.toString(this.indentation_size));
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_AFTER_OPENING_BRACE_IN_INITIALIZER_LIST, this.insert_new_line_after_opening_brace_in_initializer_list? IDEPlugin.INSERT : IDEPlugin.DO_NOT_INSERT);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_AFTER_TEMPLATE_DECLARATION, this.insert_new_line_after_template_declaration? IDEPlugin.INSERT : IDEPlugin.DO_NOT_INSERT);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_AT_END_OF_FILE_IF_MISSING, this.insert_new_line_at_end_of_file_if_missing ? IDEPlugin.INSERT : IDEPlugin.DO_NOT_INSERT);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_BEFORE_CATCH_IN_TRY_STATEMENT, this.insert_new_line_before_catch_in_try_statement? IDEPlugin.INSERT : IDEPlugin.DO_NOT_INSERT);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_BEFORE_CLOSING_BRACE_IN_INITIALIZER_LIST, this.insert_new_line_before_closing_brace_in_initializer_list? IDEPlugin.INSERT : IDEPlugin.DO_NOT_INSERT);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_BEFORE_COLON_IN_CONSTRUCTOR_INITIALIZER_LIST, this.insert_new_line_before_colon_in_constructor_initializer_list? IDEPlugin.INSERT : IDEPlugin.DO_NOT_INSERT);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_BEFORE_ELSE_IN_IF_STATEMENT, this.insert_new_line_before_else_in_if_statement? IDEPlugin.INSERT : IDEPlugin.DO_NOT_INSERT);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_BEFORE_WHILE_IN_DO_STATEMENT, this.insert_new_line_before_while_in_do_statement? IDEPlugin.INSERT : IDEPlugin.DO_NOT_INSERT);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_BEFORE_IDENTIFIER_IN_FUNCTION_DECLARATION, this.insert_new_line_before_identifier_in_function_declaration? IDEPlugin.INSERT : IDEPlugin.DO_NOT_INSERT);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_IN_EMPTY_BLOCK, this.insert_new_line_in_empty_block? IDEPlugin.INSERT : IDEPlugin.DO_NOT_INSERT);
+// options.put(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_IN_EMPTY_METHOD_BODY, this.insert_new_line_in_empty_method_body? IDEPlugin.INSERT : IDEPlugin.DO_NOT_INSERT);
+// options.put(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_IN_EMPTY_TYPE_DECLARATION, this.insert_new_line_in_empty_type_declaration? IDEPlugin.INSERT : IDEPlugin.DO_NOT_INSERT);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_ASSIGNMENT_OPERATOR, this.insert_space_after_assignment_operator? IDEPlugin.INSERT : IDEPlugin.DO_NOT_INSERT);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_BINARY_OPERATOR, this.insert_space_after_binary_operator? IDEPlugin.INSERT : IDEPlugin.DO_NOT_INSERT);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_CLOSING_ANGLE_BRACKET_IN_TEMPLATE_ARGUMENTS, this.insert_space_after_closing_angle_bracket_in_template_arguments ? IDEPlugin.INSERT : IDEPlugin.DO_NOT_INSERT);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_CLOSING_ANGLE_BRACKET_IN_TEMPLATE_PARAMETERS, this.insert_space_after_closing_angle_bracket_in_template_parameters ? IDEPlugin.INSERT : IDEPlugin.DO_NOT_INSERT);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_CLOSING_PAREN_IN_CAST, this.insert_space_after_closing_paren_in_cast? IDEPlugin.INSERT : IDEPlugin.DO_NOT_INSERT);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_CLOSING_BRACE_IN_BLOCK, this.insert_space_after_closing_brace_in_block? IDEPlugin.INSERT : IDEPlugin.DO_NOT_INSERT);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_COLON_IN_BASE_CLAUSE, this.insert_space_after_colon_in_base_clause ? IDEPlugin.INSERT : IDEPlugin.DO_NOT_INSERT);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_COLON_IN_CASE, this.insert_space_after_colon_in_case ? IDEPlugin.INSERT : IDEPlugin.DO_NOT_INSERT);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_COLON_IN_CONDITIONAL, this.insert_space_after_colon_in_conditional ? IDEPlugin.INSERT : IDEPlugin.DO_NOT_INSERT);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_COLON_IN_LABELED_STATEMENT, this.insert_space_after_colon_in_labeled_statement? IDEPlugin.INSERT : IDEPlugin.DO_NOT_INSERT);
+// options.put(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_COMMA_IN_ALLOCATION_EXPRESSION, this.insert_space_after_comma_in_allocation_expression? IDEPlugin.INSERT : IDEPlugin.DO_NOT_INSERT);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_COMMA_IN_INITIALIZER_LIST, this.insert_space_after_comma_in_initializer_list? IDEPlugin.INSERT : IDEPlugin.DO_NOT_INSERT);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_COMMA_IN_ENUM_DECLARATIONS, this.insert_space_after_comma_in_enum_declarations ? IDEPlugin.INSERT : IDEPlugin.DO_NOT_INSERT);
+// options.put(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_COMMA_IN_FOR_INCREMENTS, this.insert_space_after_comma_in_for_increments? IDEPlugin.INSERT : IDEPlugin.DO_NOT_INSERT);
+// options.put(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_COMMA_IN_FOR_INITS, this.insert_space_after_comma_in_for_inits? IDEPlugin.INSERT : IDEPlugin.DO_NOT_INSERT);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_COMMA_IN_METHOD_INVOCATION_ARGUMENTS, this.insert_space_after_comma_in_method_invocation_arguments? IDEPlugin.INSERT : IDEPlugin.DO_NOT_INSERT);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_COMMA_IN_METHOD_DECLARATION_PARAMETERS, this.insert_space_after_comma_in_method_declaration_parameters? IDEPlugin.INSERT : IDEPlugin.DO_NOT_INSERT);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_COMMA_IN_METHOD_DECLARATION_THROWS, this.insert_space_after_comma_in_method_declaration_throws? IDEPlugin.INSERT : IDEPlugin.DO_NOT_INSERT);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_COMMA_IN_DECLARATOR_LIST, this.insert_space_after_comma_in_declarator_list? IDEPlugin.INSERT : IDEPlugin.DO_NOT_INSERT);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_COMMA_IN_EXPRESSION_LIST, this.insert_space_after_comma_in_expression_list? IDEPlugin.INSERT : IDEPlugin.DO_NOT_INSERT);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_COMMA_IN_BASE_TYPES, this.insert_space_after_comma_in_base_types? IDEPlugin.INSERT : IDEPlugin.DO_NOT_INSERT);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_COMMA_IN_TEMPLATE_ARGUMENTS, this.insert_space_after_comma_in_template_arguments ? IDEPlugin.INSERT : IDEPlugin.DO_NOT_INSERT);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_COMMA_IN_TEMPLATE_PARAMETERS, this.insert_space_after_comma_in_template_parameters ? IDEPlugin.INSERT : IDEPlugin.DO_NOT_INSERT);
+// options.put(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_ELLIPSIS, this.insert_space_after_ellipsis ? IDEPlugin.INSERT : IDEPlugin.DO_NOT_INSERT);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_OPENING_ANGLE_BRACKET_IN_TEMPLATE_ARGUMENTS, this.insert_space_after_opening_angle_bracket_in_template_arguments? IDEPlugin.INSERT : IDEPlugin.DO_NOT_INSERT);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_OPENING_ANGLE_BRACKET_IN_TEMPLATE_PARAMETERS, this.insert_space_after_opening_angle_bracket_in_template_parameters? IDEPlugin.INSERT : IDEPlugin.DO_NOT_INSERT);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_OPENING_BRACKET, this.insert_space_after_opening_bracket? IDEPlugin.INSERT : IDEPlugin.DO_NOT_INSERT);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_OPENING_BRACE_IN_INITIALIZER_LIST, this.insert_space_after_opening_brace_in_initializer_list? IDEPlugin.INSERT : IDEPlugin.DO_NOT_INSERT);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_OPENING_PAREN_IN_CAST, this.insert_space_after_opening_paren_in_cast? IDEPlugin.INSERT : IDEPlugin.DO_NOT_INSERT);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_OPENING_PAREN_IN_CATCH, this.insert_space_after_opening_paren_in_catch? IDEPlugin.INSERT : IDEPlugin.DO_NOT_INSERT);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_OPENING_PAREN_IN_FOR, this.insert_space_after_opening_paren_in_for? IDEPlugin.INSERT : IDEPlugin.DO_NOT_INSERT);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_OPENING_PAREN_IN_IF, this.insert_space_after_opening_paren_in_if? IDEPlugin.INSERT : IDEPlugin.DO_NOT_INSERT);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_OPENING_PAREN_IN_METHOD_DECLARATION, this.insert_space_after_opening_paren_in_method_declaration? IDEPlugin.INSERT : IDEPlugin.DO_NOT_INSERT);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_OPENING_PAREN_IN_EXCEPTION_SPECIFICATION, this.insert_space_after_opening_paren_in_exception_specification? IDEPlugin.INSERT : IDEPlugin.DO_NOT_INSERT);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_OPENING_PAREN_IN_METHOD_INVOCATION, this.insert_space_after_opening_paren_in_method_invocation? IDEPlugin.INSERT : IDEPlugin.DO_NOT_INSERT);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_OPENING_PAREN_IN_PARENTHESIZED_EXPRESSION, this.insert_space_after_opening_paren_in_parenthesized_expression? IDEPlugin.INSERT : IDEPlugin.DO_NOT_INSERT);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_OPENING_PAREN_IN_SWITCH, this.insert_space_after_opening_paren_in_switch? IDEPlugin.INSERT : IDEPlugin.DO_NOT_INSERT);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_OPENING_PAREN_IN_WHILE, this.insert_space_after_opening_paren_in_while? IDEPlugin.INSERT : IDEPlugin.DO_NOT_INSERT);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_POSTFIX_OPERATOR, this.insert_space_after_postfix_operator? IDEPlugin.INSERT : IDEPlugin.DO_NOT_INSERT);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_PREFIX_OPERATOR, this.insert_space_after_prefix_operator? IDEPlugin.INSERT : IDEPlugin.DO_NOT_INSERT);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_QUESTION_IN_CONDITIONAL, this.insert_space_after_question_in_conditional? IDEPlugin.INSERT : IDEPlugin.DO_NOT_INSERT);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_SEMICOLON_IN_FOR, this.insert_space_after_semicolon_in_for? IDEPlugin.INSERT : IDEPlugin.DO_NOT_INSERT);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_UNARY_OPERATOR, this.insert_space_after_unary_operator? IDEPlugin.INSERT : IDEPlugin.DO_NOT_INSERT);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_ASSIGNMENT_OPERATOR, this.insert_space_before_assignment_operator? IDEPlugin.INSERT : IDEPlugin.DO_NOT_INSERT);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_BINARY_OPERATOR, this.insert_space_before_binary_operator? IDEPlugin.INSERT : IDEPlugin.DO_NOT_INSERT);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_CLOSING_ANGLE_BRACKET_IN_TEMPLATE_ARGUMENTS, this.insert_space_before_closing_angle_bracket_in_template_arguments? IDEPlugin.INSERT : IDEPlugin.DO_NOT_INSERT);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_CLOSING_ANGLE_BRACKET_IN_TEMPLATE_PARAMETERS, this.insert_space_before_closing_angle_bracket_in_template_parameters? IDEPlugin.INSERT : IDEPlugin.DO_NOT_INSERT);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_CLOSING_BRACE_IN_INITIALIZER_LIST, this.insert_space_before_closing_brace_in_initializer_list? IDEPlugin.INSERT : IDEPlugin.DO_NOT_INSERT);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_CLOSING_BRACKET, this.insert_space_before_closing_bracket? IDEPlugin.INSERT : IDEPlugin.DO_NOT_INSERT);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_CLOSING_PAREN_IN_CAST, this.insert_space_before_closing_paren_in_cast? IDEPlugin.INSERT : IDEPlugin.DO_NOT_INSERT);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_CLOSING_PAREN_IN_CATCH, this.insert_space_before_closing_paren_in_catch? IDEPlugin.INSERT : IDEPlugin.DO_NOT_INSERT);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_CLOSING_PAREN_IN_FOR, this.insert_space_before_closing_paren_in_for? IDEPlugin.INSERT : IDEPlugin.DO_NOT_INSERT);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_CLOSING_PAREN_IN_IF, this.insert_space_before_closing_paren_in_if? IDEPlugin.INSERT : IDEPlugin.DO_NOT_INSERT);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_CLOSING_PAREN_IN_METHOD_DECLARATION, this.insert_space_before_closing_paren_in_method_declaration? IDEPlugin.INSERT : IDEPlugin.DO_NOT_INSERT);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_CLOSING_PAREN_IN_EXCEPTION_SPECIFICATION, this.insert_space_before_closing_paren_in_exception_specification? IDEPlugin.INSERT : IDEPlugin.DO_NOT_INSERT);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_CLOSING_PAREN_IN_METHOD_INVOCATION, this.insert_space_before_closing_paren_in_method_invocation? IDEPlugin.INSERT : IDEPlugin.DO_NOT_INSERT);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_CLOSING_PAREN_IN_PARENTHESIZED_EXPRESSION, this.insert_space_before_closing_paren_in_parenthesized_expression? IDEPlugin.INSERT : IDEPlugin.DO_NOT_INSERT);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_CLOSING_PAREN_IN_SWITCH, this.insert_space_before_closing_paren_in_switch? IDEPlugin.INSERT : IDEPlugin.DO_NOT_INSERT);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_CLOSING_PAREN_IN_WHILE, this.insert_space_before_closing_paren_in_while? IDEPlugin.INSERT : IDEPlugin.DO_NOT_INSERT);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_COLON_IN_BASE_CLAUSE, this.insert_space_before_colon_in_base_clause? IDEPlugin.INSERT : IDEPlugin.DO_NOT_INSERT);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_COLON_IN_CASE, this.insert_space_before_colon_in_case? IDEPlugin.INSERT : IDEPlugin.DO_NOT_INSERT);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_COLON_IN_CONDITIONAL, this.insert_space_before_colon_in_conditional? IDEPlugin.INSERT : IDEPlugin.DO_NOT_INSERT);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_COLON_IN_DEFAULT, this.insert_space_before_colon_in_default? IDEPlugin.INSERT : IDEPlugin.DO_NOT_INSERT);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_COLON_IN_LABELED_STATEMENT, this.insert_space_before_colon_in_labeled_statement? IDEPlugin.INSERT : IDEPlugin.DO_NOT_INSERT);
+// options.put(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_COMMA_IN_ALLOCATION_EXPRESSION, this.insert_space_before_comma_in_allocation_expression? IDEPlugin.INSERT : IDEPlugin.DO_NOT_INSERT);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_COMMA_IN_INITIALIZER_LIST, this.insert_space_before_comma_in_initializer_list? IDEPlugin.INSERT : IDEPlugin.DO_NOT_INSERT);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_COMMA_IN_ENUM_DECLARATIONS, this.insert_space_before_comma_in_enum_declarations? IDEPlugin.INSERT : IDEPlugin.DO_NOT_INSERT);
+// options.put(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_COMMA_IN_FOR_INCREMENTS, this.insert_space_before_comma_in_for_increments? IDEPlugin.INSERT : IDEPlugin.DO_NOT_INSERT);
+// options.put(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_COMMA_IN_FOR_INITS, this.insert_space_before_comma_in_for_inits? IDEPlugin.INSERT : IDEPlugin.DO_NOT_INSERT);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_COMMA_IN_METHOD_INVOCATION_ARGUMENTS, this.insert_space_before_comma_in_method_invocation_arguments? IDEPlugin.INSERT : IDEPlugin.DO_NOT_INSERT);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_COMMA_IN_METHOD_DECLARATION_PARAMETERS, this.insert_space_before_comma_in_method_declaration_parameters? IDEPlugin.INSERT : IDEPlugin.DO_NOT_INSERT);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_COMMA_IN_METHOD_DECLARATION_THROWS, this.insert_space_before_comma_in_method_declaration_throws? IDEPlugin.INSERT : IDEPlugin.DO_NOT_INSERT);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_COMMA_IN_DECLARATOR_LIST, this.insert_space_before_comma_in_declarator_list? IDEPlugin.INSERT : IDEPlugin.DO_NOT_INSERT);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_COMMA_IN_EXPRESSION_LIST, this.insert_space_before_comma_in_expression_list? IDEPlugin.INSERT : IDEPlugin.DO_NOT_INSERT);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_COMMA_IN_BASE_TYPES, this.insert_space_before_comma_in_base_types? IDEPlugin.INSERT : IDEPlugin.DO_NOT_INSERT);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_COMMA_IN_TEMPLATE_ARGUMENTS, this.insert_space_before_comma_in_template_arguments ? IDEPlugin.INSERT : IDEPlugin.DO_NOT_INSERT);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_COMMA_IN_TEMPLATE_PARAMETERS, this.insert_space_before_comma_in_template_parameters? IDEPlugin.INSERT : IDEPlugin.DO_NOT_INSERT);
+// options.put(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_ELLIPSIS, this.insert_space_before_ellipsis ? IDEPlugin.INSERT : IDEPlugin.DO_NOT_INSERT);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_OPENING_ANGLE_BRACKET_IN_TEMPLATE_ARGUMENTS, this.insert_space_before_opening_angle_bracket_in_template_arguments? IDEPlugin.INSERT : IDEPlugin.DO_NOT_INSERT);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_OPENING_ANGLE_BRACKET_IN_TEMPLATE_PARAMETERS, this.insert_space_before_opening_angle_bracket_in_template_parameters? IDEPlugin.INSERT : IDEPlugin.DO_NOT_INSERT);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_OPENING_BRACE_IN_INITIALIZER_LIST, this.insert_space_before_opening_brace_in_initializer_list? IDEPlugin.INSERT : IDEPlugin.DO_NOT_INSERT);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_OPENING_BRACE_IN_BLOCK, this.insert_space_before_opening_brace_in_block? IDEPlugin.INSERT : IDEPlugin.DO_NOT_INSERT);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_OPENING_BRACE_IN_METHOD_DECLARATION, this.insert_space_before_opening_brace_in_method_declaration? IDEPlugin.INSERT : IDEPlugin.DO_NOT_INSERT);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_OPENING_BRACE_IN_TYPE_DECLARATION, this.insert_space_before_opening_brace_in_type_declaration? IDEPlugin.INSERT : IDEPlugin.DO_NOT_INSERT);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_OPENING_BRACE_IN_NAMESPACE_DECLARATION, this.insert_space_before_opening_brace_in_namespace_declaration? IDEPlugin.INSERT : IDEPlugin.DO_NOT_INSERT);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_OPENING_BRACKET, this.insert_space_before_opening_bracket? IDEPlugin.INSERT : IDEPlugin.DO_NOT_INSERT);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_OPENING_PAREN_IN_CATCH, this.insert_space_before_opening_paren_in_catch? IDEPlugin.INSERT : IDEPlugin.DO_NOT_INSERT);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_OPENING_PAREN_IN_FOR, this.insert_space_before_opening_paren_in_for? IDEPlugin.INSERT : IDEPlugin.DO_NOT_INSERT);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_OPENING_PAREN_IN_IF, this.insert_space_before_opening_paren_in_if? IDEPlugin.INSERT : IDEPlugin.DO_NOT_INSERT);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_OPENING_PAREN_IN_METHOD_INVOCATION, this.insert_space_before_opening_paren_in_method_invocation? IDEPlugin.INSERT : IDEPlugin.DO_NOT_INSERT);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_OPENING_PAREN_IN_METHOD_DECLARATION, this.insert_space_before_opening_paren_in_method_declaration? IDEPlugin.INSERT : IDEPlugin.DO_NOT_INSERT);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_OPENING_PAREN_IN_EXCEPTION_SPECIFICATION, this.insert_space_before_opening_paren_in_exception_specification? IDEPlugin.INSERT : IDEPlugin.DO_NOT_INSERT);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_OPENING_PAREN_IN_SWITCH, this.insert_space_before_opening_paren_in_switch? IDEPlugin.INSERT : IDEPlugin.DO_NOT_INSERT);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_OPENING_BRACE_IN_SWITCH, this.insert_space_before_opening_brace_in_switch? IDEPlugin.INSERT : IDEPlugin.DO_NOT_INSERT);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_OPENING_PAREN_IN_PARENTHESIZED_EXPRESSION, this.insert_space_before_opening_paren_in_parenthesized_expression? IDEPlugin.INSERT : IDEPlugin.DO_NOT_INSERT);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_OPENING_PAREN_IN_WHILE, this.insert_space_before_opening_paren_in_while? IDEPlugin.INSERT : IDEPlugin.DO_NOT_INSERT);
+// options.put(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_PARENTHESIZED_EXPRESSION_IN_RETURN, this.insert_space_before_parenthesized_expression_in_return ? IDEPlugin.INSERT : IDEPlugin.DO_NOT_INSERT);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_POSTFIX_OPERATOR, this.insert_space_before_postfix_operator? IDEPlugin.INSERT : IDEPlugin.DO_NOT_INSERT);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_PREFIX_OPERATOR, this.insert_space_before_prefix_operator? IDEPlugin.INSERT : IDEPlugin.DO_NOT_INSERT);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_QUESTION_IN_CONDITIONAL, this.insert_space_before_question_in_conditional? IDEPlugin.INSERT : IDEPlugin.DO_NOT_INSERT);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_SEMICOLON, this.insert_space_before_semicolon? IDEPlugin.INSERT : IDEPlugin.DO_NOT_INSERT);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_SEMICOLON_IN_FOR, this.insert_space_before_semicolon_in_for? IDEPlugin.INSERT : IDEPlugin.DO_NOT_INSERT);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_UNARY_OPERATOR, this.insert_space_before_unary_operator? IDEPlugin.INSERT : IDEPlugin.DO_NOT_INSERT);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BETWEEN_EMPTY_BRACES_IN_INITIALIZER_LIST, this.insert_space_between_empty_braces_in_initializer_list? IDEPlugin.INSERT : IDEPlugin.DO_NOT_INSERT);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BETWEEN_EMPTY_BRACKETS, this.insert_space_between_empty_brackets? IDEPlugin.INSERT : IDEPlugin.DO_NOT_INSERT);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BETWEEN_EMPTY_PARENS_IN_METHOD_DECLARATION, this.insert_space_between_empty_parens_in_method_declaration? IDEPlugin.INSERT : IDEPlugin.DO_NOT_INSERT);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BETWEEN_EMPTY_PARENS_IN_METHOD_INVOCATION, this.insert_space_between_empty_parens_in_method_invocation? IDEPlugin.INSERT : IDEPlugin.DO_NOT_INSERT);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BETWEEN_EMPTY_PARENS_IN_EXCEPTION_SPECIFICATION, this.insert_space_between_empty_parens_in_exception_specification? IDEPlugin.INSERT : IDEPlugin.DO_NOT_INSERT);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_COMPACT_ELSE_IF, this.compact_else_if ? STPDefaultCodeFormatterConstants.TRUE : STPDefaultCodeFormatterConstants.FALSE);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_KEEP_GUARDIAN_CLAUSE_ON_ONE_LINE, this.keep_guardian_clause_on_one_line ? STPDefaultCodeFormatterConstants.TRUE : STPDefaultCodeFormatterConstants.FALSE);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_KEEP_ELSE_STATEMENT_ON_SAME_LINE, this.keep_else_statement_on_same_line ? STPDefaultCodeFormatterConstants.TRUE : STPDefaultCodeFormatterConstants.FALSE);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_KEEP_EMPTY_INITIALIZER_LIST_ON_ONE_LINE, this.keep_empty_initializer_list_on_one_line ? STPDefaultCodeFormatterConstants.TRUE : STPDefaultCodeFormatterConstants.FALSE);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_KEEP_SIMPLE_IF_ON_ONE_LINE, this.keep_simple_if_on_one_line ? STPDefaultCodeFormatterConstants.TRUE : STPDefaultCodeFormatterConstants.FALSE);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_KEEP_THEN_STATEMENT_ON_SAME_LINE, this.keep_then_statement_on_same_line ? STPDefaultCodeFormatterConstants.TRUE : STPDefaultCodeFormatterConstants.FALSE);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_NUMBER_OF_EMPTY_LINES_TO_PRESERVE, Integer.toString(this.number_of_empty_lines_to_preserve));
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_JOIN_WRAPPED_LINES, this.join_wrapped_lines ? STPDefaultCodeFormatterConstants.TRUE : STPDefaultCodeFormatterConstants.FALSE);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_PUT_EMPTY_STATEMENT_ON_NEW_LINE, this.put_empty_statement_on_new_line ? STPDefaultCodeFormatterConstants.TRUE : STPDefaultCodeFormatterConstants.FALSE);
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_LINE_SPLIT, Integer.toString(this.page_width));
+ switch (this.tab_char) {
+ case SPACE:
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_TAB_CHAR, IDEPlugin.SPACE);
+ break;
+ case TAB:
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_TAB_CHAR, IDEPlugin.TAB);
+ break;
+ case MIXED:
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_TAB_CHAR, STPDefaultCodeFormatterConstants.MIXED);
+ break;
+ }
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_TAB_SIZE, Integer.toString(this.tab_size));
+ options.put(STPDefaultCodeFormatterConstants.FORMATTER_USE_TABS_ONLY_FOR_LEADING_INDENTATIONS, this.use_tabs_only_for_leading_indentations ? STPDefaultCodeFormatterConstants.TRUE : STPDefaultCodeFormatterConstants.FALSE);
+ return options;
+ }
+
+ public void set(Map<String, String> settings) {
+// final Object alignmentForArgumentsInAllocationExpressionOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_ARGUMENTS_IN_ALLOCATION_EXPRESSION);
+// if (alignmentForArgumentsInAllocationExpressionOption != null) {
+// try {
+// this.alignment_for_arguments_in_allocation_expression = Integer.parseInt((String) alignmentForArgumentsInAllocationExpressionOption);
+// } catch (NumberFormatException e) {
+// this.alignment_for_arguments_in_allocation_expression = Alignment.M_COMPACT_SPLIT;
+// } catch (ClassCastException e) {
+// this.alignment_for_arguments_in_allocation_expression = Alignment.M_COMPACT_SPLIT;
+// }
+// }
+ final Object alignmentForArgumentsInMethodInvocationOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_ARGUMENTS_IN_METHOD_INVOCATION);
+ if (alignmentForArgumentsInMethodInvocationOption != null) {
+ try {
+ this.alignment_for_arguments_in_method_invocation = Integer.parseInt((String) alignmentForArgumentsInMethodInvocationOption);
+ } catch (NumberFormatException e) {
+ this.alignment_for_arguments_in_method_invocation = STPAlignment.M_COMPACT_SPLIT;
+ } catch (ClassCastException e) {
+ this.alignment_for_arguments_in_method_invocation = STPAlignment.M_COMPACT_SPLIT;
+ }
+ }
+ final Object alignmentForAssignmentOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_ASSIGNMENT);
+ if (alignmentForAssignmentOption != null) {
+ try {
+ this.alignment_for_assignment = Integer.parseInt((String) alignmentForAssignmentOption);
+ } catch (NumberFormatException e) {
+ this.alignment_for_assignment = STPAlignment.M_COMPACT_SPLIT;
+ } catch (ClassCastException e) {
+ this.alignment_for_assignment = STPAlignment.M_COMPACT_SPLIT;
+ }
+ }
+ final Object alignmentForBinaryExpressionOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_BINARY_EXPRESSION);
+ if (alignmentForBinaryExpressionOption != null) {
+ try {
+ this.alignment_for_binary_expression = Integer.parseInt((String) alignmentForBinaryExpressionOption);
+ } catch (NumberFormatException e) {
+ this.alignment_for_binary_expression = STPAlignment.M_COMPACT_SPLIT;
+ } catch (ClassCastException e) {
+ this.alignment_for_binary_expression = STPAlignment.M_COMPACT_SPLIT;
+ }
+ }
+ final Object alignmentForCompactIfOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_COMPACT_IF);
+ if (alignmentForCompactIfOption != null) {
+ try {
+ this.alignment_for_compact_if = Integer.parseInt((String) alignmentForCompactIfOption);
+ } catch (NumberFormatException e) {
+ this.alignment_for_compact_if = STPAlignment.M_ONE_PER_LINE_SPLIT | STPAlignment.M_INDENT_BY_ONE;
+ } catch (ClassCastException e) {
+ this.alignment_for_compact_if = STPAlignment.M_ONE_PER_LINE_SPLIT | STPAlignment.M_INDENT_BY_ONE;
+ }
+ }
+ final Object alignmentForConditionalExpressionOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_CONDITIONAL_EXPRESSION);
+ if (alignmentForConditionalExpressionOption != null) {
+ try {
+ this.alignment_for_conditional_expression = Integer.parseInt((String) alignmentForConditionalExpressionOption);
+ } catch (NumberFormatException e) {
+ this.alignment_for_conditional_expression = STPAlignment.M_COMPACT_FIRST_BREAK_SPLIT | STPAlignment.M_INDENT_ON_COLUMN;
+ } catch (ClassCastException e) {
+ this.alignment_for_conditional_expression = STPAlignment.M_COMPACT_FIRST_BREAK_SPLIT | STPAlignment.M_INDENT_ON_COLUMN;
+ }
+ }
+ final Object alignmentForConditionalExpressionChainOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_CONDITIONAL_EXPRESSION_CHAIN);
+ if (alignmentForConditionalExpressionChainOption != null) {
+ try {
+ this.alignment_for_conditional_expression_chain = Integer.parseInt((String) alignmentForConditionalExpressionChainOption);
+ } catch (NumberFormatException e) {
+ this.alignment_for_conditional_expression_chain = STPAlignment.M_COMPACT_SPLIT | STPAlignment.M_INDENT_ON_COLUMN;
+ } catch (ClassCastException e) {
+ this.alignment_for_conditional_expression_chain = STPAlignment.M_COMPACT_SPLIT | STPAlignment.M_INDENT_ON_COLUMN;
+ }
+ }
+ final Object alignmentForDeclaratorListOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_DECLARATOR_LIST);
+ if (alignmentForDeclaratorListOption != null) {
+ try {
+ this.alignment_for_declarator_list = Integer.parseInt((String) alignmentForDeclaratorListOption);
+ } catch (NumberFormatException e) {
+ this.alignment_for_declarator_list = STPAlignment.M_COMPACT_SPLIT;
+ } catch (ClassCastException e) {
+ this.alignment_for_declarator_list = STPAlignment.M_COMPACT_SPLIT;
+ }
+ }
+ final Object alignmentForEnumeratorListOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_ENUMERATOR_LIST);
+ if (alignmentForEnumeratorListOption != null) {
+ try {
+ this.alignment_for_enumerator_list = Integer.parseInt((String) alignmentForEnumeratorListOption);
+ } catch (NumberFormatException e) {
+ this.alignment_for_enumerator_list = STPAlignment.M_ONE_PER_LINE_SPLIT;
+ } catch (ClassCastException e) {
+ this.alignment_for_enumerator_list = STPAlignment.M_ONE_PER_LINE_SPLIT;
+ }
+ }
+ final Object alignmentForExpressionsInInitializerListOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_EXPRESSIONS_IN_INITIALIZER_LIST);
+ if (alignmentForExpressionsInInitializerListOption != null) {
+ try {
+ this.alignment_for_expressions_in_initializer_list = Integer.parseInt((String) alignmentForExpressionsInInitializerListOption);
+ } catch (NumberFormatException e) {
+ this.alignment_for_expressions_in_initializer_list = STPAlignment.M_COMPACT_SPLIT;
+ } catch (ClassCastException e) {
+ this.alignment_for_expressions_in_initializer_list = STPAlignment.M_COMPACT_SPLIT;
+ }
+ }
+ final Object alignmentForExpressionListOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_EXPRESSION_LIST);
+ if (alignmentForExpressionListOption != null) {
+ try {
+ this.alignment_for_expression_list = Integer.parseInt((String) alignmentForExpressionListOption);
+ } catch (NumberFormatException e) {
+ this.alignment_for_expression_list = STPAlignment.M_COMPACT_SPLIT;
+ } catch (ClassCastException e) {
+ this.alignment_for_expression_list = STPAlignment.M_COMPACT_SPLIT;
+ }
+ }
+ final Object alignmentForMemberAccessOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_MEMBER_ACCESS);
+ if (alignmentForMemberAccessOption != null) {
+ try {
+ this.alignment_for_member_access = Integer.parseInt((String) alignmentForMemberAccessOption);
+ } catch (NumberFormatException e) {
+ this.alignment_for_member_access = STPAlignment.M_ONE_PER_LINE_SPLIT;
+ } catch (ClassCastException e) {
+ this.alignment_for_member_access = STPAlignment.M_ONE_PER_LINE_SPLIT;
+ }
+ }
+ final Object alignmentForOverloadedLeftShiftChainOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_OVERLOADED_LEFT_SHIFT_CHAIN);
+ if (alignmentForOverloadedLeftShiftChainOption != null) {
+ try {
+ this.alignment_for_overloaded_left_shift_chain = Integer.parseInt((String) alignmentForOverloadedLeftShiftChainOption);
+ } catch (NumberFormatException e) {
+ this.alignment_for_overloaded_left_shift_chain = STPAlignment.M_COMPACT_SPLIT;
+ } catch (ClassCastException e) {
+ this.alignment_for_overloaded_left_shift_chain = STPAlignment.M_COMPACT_SPLIT;
+ }
+ }
+ final Object alignmentForParametersInMethodDeclarationOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_PARAMETERS_IN_METHOD_DECLARATION);
+ if (alignmentForParametersInMethodDeclarationOption != null) {
+ try {
+ this.alignment_for_parameters_in_method_declaration = Integer.parseInt((String) alignmentForParametersInMethodDeclarationOption);
+ } catch (NumberFormatException e) {
+ this.alignment_for_parameters_in_method_declaration = STPAlignment.M_COMPACT_SPLIT;
+ } catch (ClassCastException e) {
+ this.alignment_for_parameters_in_method_declaration = STPAlignment.M_COMPACT_SPLIT;
+ }
+ }
+ final Object alignmentForBaseClauseInTypeDeclarationOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_BASE_CLAUSE_IN_TYPE_DECLARATION);
+ if (alignmentForBaseClauseInTypeDeclarationOption != null) {
+ try {
+ this.alignment_for_base_clause_in_type_declaration = Integer.parseInt((String) alignmentForBaseClauseInTypeDeclarationOption);
+ } catch (NumberFormatException e) {
+ this.alignment_for_base_clause_in_type_declaration = STPAlignment.M_NEXT_SHIFTED_SPLIT;
+ } catch (ClassCastException e) {
+ this.alignment_for_base_clause_in_type_declaration = STPAlignment.M_NEXT_SHIFTED_SPLIT;
+ }
+ }
+ final Object alignmentForConstructorInitializerListOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_CONSTRUCTOR_INITIALIZER_LIST);
+ if (alignmentForConstructorInitializerListOption != null) {
+ try {
+ this.alignment_for_constructor_initializer_list = Integer.parseInt((String) alignmentForConstructorInitializerListOption);
+ } catch (NumberFormatException e) {
+ this.alignment_for_constructor_initializer_list = STPAlignment.M_COMPACT_SPLIT;
+ } catch (ClassCastException e) {
+ this.alignment_for_constructor_initializer_list = STPAlignment.M_COMPACT_SPLIT;
+ }
+ }
+ final Object alignmentForThrowsClauseInMethodDeclarationOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_THROWS_CLAUSE_IN_METHOD_DECLARATION);
+ if (alignmentForThrowsClauseInMethodDeclarationOption != null) {
+ try {
+ this.alignment_for_throws_clause_in_method_declaration = Integer.parseInt((String) alignmentForThrowsClauseInMethodDeclarationOption);
+ } catch (NumberFormatException e) {
+ this.alignment_for_throws_clause_in_method_declaration = STPAlignment.M_COMPACT_SPLIT;
+ } catch (ClassCastException e) {
+ this.alignment_for_throws_clause_in_method_declaration = STPAlignment.M_COMPACT_SPLIT;
+ }
+ }
+// final Object alignTypeMembersOnColumnsOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_ALIGN_TYPE_MEMBERS_ON_COLUMNS);
+// if (alignTypeMembersOnColumnsOption != null) {
+// this.align_type_members_on_columns = STPDefaultCodeFormatterConstants.TRUE.equals(alignTypeMembersOnColumnsOption);
+// }
+// final Object blankLinesAfterIncludesOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_BLANK_LINES_AFTER_IMPORTS);
+// if (blankLinesAfterIncludesOption != null) {
+// try {
+// this.blank_lines_after_includes = Integer.parseInt((String) blankLinesAfterIncludesOption);
+// } catch (NumberFormatException e) {
+// this.blank_lines_after_includes = 0;
+// } catch (ClassCastException e) {
+// this.blank_lines_after_includes = 0;
+// }
+// }
+// final Object blankLinesBeforeFieldOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_BLANK_LINES_BEFORE_FIELD);
+// if (blankLinesBeforeFieldOption != null) {
+// try {
+// this.blank_lines_before_field = Integer.parseInt((String) blankLinesBeforeFieldOption);
+// } catch (NumberFormatException e) {
+// this.blank_lines_before_field = 0;
+// } catch (ClassCastException e) {
+// this.blank_lines_before_field = 0;
+// }
+// }
+// final Object blankLinesBeforeFirstClassBodyDeclarationOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_BLANK_LINES_BEFORE_FIRST_CLASS_BODY_DECLARATION);
+// if (blankLinesBeforeFirstClassBodyDeclarationOption != null) {
+// try {
+// this.blank_lines_before_first_class_body_declaration = Integer.parseInt((String) blankLinesBeforeFirstClassBodyDeclarationOption);
+// } catch (NumberFormatException e) {
+// this.blank_lines_before_first_class_body_declaration = 0;
+// } catch (ClassCastException e) {
+// this.blank_lines_before_first_class_body_declaration = 0;
+// }
+// }
+// final Object blankLinesBeforeIncludesOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_BLANK_LINES_BEFORE_IMPORTS);
+// if (blankLinesBeforeIncludesOption != null) {
+// try {
+// this.blank_lines_before_includes = Integer.parseInt((String) blankLinesBeforeIncludesOption);
+// } catch (NumberFormatException e) {
+// this.blank_lines_before_includes = 0;
+// } catch (ClassCastException e) {
+// this.blank_lines_before_includes = 0;
+// }
+// }
+// final Object blankLinesBeforeMemberTypeOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_BLANK_LINES_BEFORE_MEMBER_TYPE);
+// if (blankLinesBeforeMemberTypeOption != null) {
+// try {
+// this.blank_lines_before_member_type = Integer.parseInt((String) blankLinesBeforeMemberTypeOption);
+// } catch (NumberFormatException e) {
+// this.blank_lines_before_member_type = 0;
+// } catch (ClassCastException e) {
+// this.blank_lines_before_member_type = 0;
+// }
+// }
+// final Object blankLinesBeforeMethodOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_BLANK_LINES_BEFORE_METHOD);
+// if (blankLinesBeforeMethodOption != null) {
+// try {
+// this.blank_lines_before_method = Integer.parseInt((String) blankLinesBeforeMethodOption);
+// } catch (NumberFormatException e) {
+// this.blank_lines_before_method = 0;
+// } catch (ClassCastException e) {
+// this.blank_lines_before_method = 0;
+// }
+// }
+// final Object blankLinesBeforeNewChunkOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_BLANK_LINES_BEFORE_NEW_CHUNK);
+// if (blankLinesBeforeNewChunkOption != null) {
+// try {
+// this.blank_lines_before_new_chunk = Integer.parseInt((String) blankLinesBeforeNewChunkOption);
+// } catch (NumberFormatException e) {
+// this.blank_lines_before_new_chunk = 0;
+// } catch (ClassCastException e) {
+// this.blank_lines_before_new_chunk = 0;
+// }
+// }
+// final Object blankLinesBetweenTypeDeclarationsOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_BLANK_LINES_BETWEEN_TYPE_DECLARATIONS);
+// if (blankLinesBetweenTypeDeclarationsOption != null) {
+// try {
+// this.blank_lines_between_type_declarations = Integer.parseInt((String) blankLinesBetweenTypeDeclarationsOption);
+// } catch (NumberFormatException e) {
+// this.blank_lines_between_type_declarations = 0;
+// } catch (ClassCastException e) {
+// this.blank_lines_between_type_declarations = 0;
+// }
+// }
+// final Object blankLinesAtBeginningOfMethodBodyOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_BLANK_LINES_AT_BEGINNING_OF_METHOD_BODY);
+// if (blankLinesAtBeginningOfMethodBodyOption != null) {
+// try {
+// this.blank_lines_at_beginning_of_method_body = Integer.parseInt((String) blankLinesAtBeginningOfMethodBodyOption);
+// } catch (NumberFormatException e) {
+// this.blank_lines_at_beginning_of_method_body = 0;
+// } catch (ClassCastException e) {
+// this.blank_lines_at_beginning_of_method_body = 0;
+// }
+// }
+ final Object bracePositionForInitializerListOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_BRACE_POSITION_FOR_INITIALIZER_LIST);
+ if (bracePositionForInitializerListOption != null) {
+ try {
+ this.brace_position_for_initializer_list = (String) bracePositionForInitializerListOption;
+ } catch (ClassCastException e) {
+ this.brace_position_for_initializer_list = STPDefaultCodeFormatterConstants.END_OF_LINE;
+ }
+ }
+ final Object bracePositionForBlockOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_BRACE_POSITION_FOR_BLOCK);
+ if (bracePositionForBlockOption != null) {
+ try {
+ this.brace_position_for_block = (String) bracePositionForBlockOption;
+ } catch (ClassCastException e) {
+ this.brace_position_for_block = STPDefaultCodeFormatterConstants.END_OF_LINE;
+ }
+ }
+ final Object bracePositionForBlockInCaseOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_BRACE_POSITION_FOR_BLOCK_IN_CASE);
+ if (bracePositionForBlockInCaseOption != null) {
+ try {
+ this.brace_position_for_block_in_case = (String) bracePositionForBlockInCaseOption;
+ } catch (ClassCastException e) {
+ this.brace_position_for_block_in_case = STPDefaultCodeFormatterConstants.END_OF_LINE;
+ }
+ }
+// final Object bracePositionForEnumDeclarationOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_BRACE_POSITION_FOR_ENUM_DECLARATION);
+// if (bracePositionForEnumDeclarationOption != null) {
+// try {
+// this.brace_position_for_enum_declaration = (String) bracePositionForEnumDeclarationOption;
+// } catch (ClassCastException e) {
+// this.brace_position_for_enum_declaration = STPDefaultCodeFormatterConstants.END_OF_LINE;
+// }
+// }
+ final Object bracePositionForMethodDeclarationOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_BRACE_POSITION_FOR_METHOD_DECLARATION);
+ if (bracePositionForMethodDeclarationOption != null) {
+ try {
+ this.brace_position_for_method_declaration = (String) bracePositionForMethodDeclarationOption;
+ } catch (ClassCastException e) {
+ this.brace_position_for_method_declaration = STPDefaultCodeFormatterConstants.END_OF_LINE;
+ }
+ }
+ final Object bracePositionForSwitchOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_BRACE_POSITION_FOR_SWITCH);
+ if (bracePositionForSwitchOption != null) {
+ try {
+ this.brace_position_for_switch = (String) bracePositionForSwitchOption;
+ } catch (ClassCastException e) {
+ this.brace_position_for_switch = STPDefaultCodeFormatterConstants.END_OF_LINE;
+ }
+ }
+ final Object bracePositionForTypeDeclarationOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_BRACE_POSITION_FOR_TYPE_DECLARATION);
+ if (bracePositionForTypeDeclarationOption != null) {
+ try {
+ this.brace_position_for_type_declaration = (String) bracePositionForTypeDeclarationOption;
+ } catch (ClassCastException e) {
+ this.brace_position_for_type_declaration = STPDefaultCodeFormatterConstants.END_OF_LINE;
+ }
+ }
+ final Object bracePositionForNamespaceDeclarationOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_BRACE_POSITION_FOR_NAMESPACE_DECLARATION);
+ if (bracePositionForNamespaceDeclarationOption != null) {
+ try {
+ this.brace_position_for_namespace_declaration = (String) bracePositionForNamespaceDeclarationOption;
+ } catch (ClassCastException e) {
+ this.brace_position_for_namespace_declaration = STPDefaultCodeFormatterConstants.END_OF_LINE;
+ }
+ }
+// final Object commentClearBlankLinesOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_COMMENT_CLEAR_BLANK_LINES);
+// if (commentClearBlankLinesOption != null) {
+// this.comment_clear_blank_lines = STPDefaultCodeFormatterConstants.TRUE.equals(commentClearBlankLinesOption);
+// }
+// final Object commentFormatOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_COMMENT_FORMAT);
+// if (commentFormatOption != null) {
+// this.comment_format = STPDefaultCodeFormatterConstants.TRUE.equals(commentFormatOption);
+// }
+// final Object commentFormatHeaderOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_COMMENT_FORMAT_HEADER);
+// if (commentFormatHeaderOption != null) {
+// this.comment_format_header = STPDefaultCodeFormatterConstants.TRUE.equals(commentFormatHeaderOption);
+// }
+// final Object commentFormatHtmlOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_COMMENT_FORMAT_HTML);
+// if (commentFormatHtmlOption != null) {
+// this.comment_format_html = STPDefaultCodeFormatterConstants.TRUE.equals(commentFormatHtmlOption);
+// }
+// final Object commentFormatSourceOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_COMMENT_FORMAT_SOURCE);
+// if (commentFormatSourceOption != null) {
+// this.comment_format_source = STPDefaultCodeFormatterConstants.TRUE.equals(commentFormatSourceOption);
+// }
+// final Object commentLineLengthOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_COMMENT_LINE_LENGTH);
+// if (commentLineLengthOption != null) {
+// try {
+// this.comment_line_length = Integer.parseInt((String) commentLineLengthOption);
+// } catch (NumberFormatException e) {
+// this.comment_line_length = 80;
+// } catch (ClassCastException e) {
+// this.comment_line_length = 80;
+// }
+// }
+ final Object commentMinDistanceBetweenCodeAndLineCommentOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_COMMENT_MIN_DISTANCE_BETWEEN_CODE_AND_LINE_COMMENT);
+ if (commentMinDistanceBetweenCodeAndLineCommentOption != null) {
+ try {
+ this.comment_min_distance_between_code_and_line_comment = Integer.parseInt((String) commentMinDistanceBetweenCodeAndLineCommentOption);
+ } catch (NumberFormatException e) {
+ this.comment_min_distance_between_code_and_line_comment = 1;
+ } catch (ClassCastException e) {
+ this.comment_min_distance_between_code_and_line_comment = 1;
+ }
+ }
+ final Object commentPreserveWhiteSpaceBetweenCodeAndLineCommentOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_COMMENT_PRESERVE_WHITE_SPACE_BETWEEN_CODE_AND_LINE_COMMENT);
+ if (commentPreserveWhiteSpaceBetweenCodeAndLineCommentOption != null) {
+ this.comment_preserve_white_space_between_code_and_line_comment = STPDefaultCodeFormatterConstants.TRUE.equals(commentPreserveWhiteSpaceBetweenCodeAndLineCommentOption);
+ }
+ final Object neverIndentLineCommentsOnFirstColumn = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_COMMENT_NEVER_INDENT_LINE_COMMENTS_ON_FIRST_COLUMN);
+ if (neverIndentLineCommentsOnFirstColumn != null) {
+ this.never_indent_line_comments_on_first_column = STPDefaultCodeFormatterConstants.TRUE.equals(neverIndentLineCommentsOnFirstColumn);
+ }
+ final Object continuationIndentationOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_CONTINUATION_INDENTATION);
+ if (continuationIndentationOption != null) {
+ try {
+ this.continuation_indentation = Integer.parseInt((String) continuationIndentationOption);
+ } catch (NumberFormatException e) {
+ this.continuation_indentation = 2;
+ } catch (ClassCastException e) {
+ this.continuation_indentation = 2;
+ }
+ }
+ final Object continuationIndentationForInitializerListOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_CONTINUATION_INDENTATION_FOR_INITIALIZER_LIST);
+ if (continuationIndentationForInitializerListOption != null) {
+ try {
+ this.continuation_indentation_for_initializer_list = Integer.parseInt((String) continuationIndentationForInitializerListOption);
+ } catch (NumberFormatException e) {
+ this.continuation_indentation_for_initializer_list = 2;
+ } catch (ClassCastException e) {
+ this.continuation_indentation_for_initializer_list = 2;
+ }
+ }
+ final Object indentStatementsCompareToBlockOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INDENT_STATEMENTS_COMPARE_TO_BLOCK);
+ if (indentStatementsCompareToBlockOption != null) {
+ this.indent_statements_compare_to_block = STPDefaultCodeFormatterConstants.TRUE.equals(indentStatementsCompareToBlockOption);
+ }
+ final Object indentStatementsCompareToBodyOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INDENT_STATEMENTS_COMPARE_TO_BODY);
+ if (indentStatementsCompareToBodyOption != null) {
+ this.indent_statements_compare_to_body = STPDefaultCodeFormatterConstants.TRUE.equals(indentStatementsCompareToBodyOption);
+ }
+ final Object indentAccessSpecifierCompareToTypeHeaderOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INDENT_ACCESS_SPECIFIER_COMPARE_TO_TYPE_HEADER);
+ if (indentAccessSpecifierCompareToTypeHeaderOption != null) {
+ this.indent_access_specifier_compare_to_type_header = STPDefaultCodeFormatterConstants.TRUE.equals(indentAccessSpecifierCompareToTypeHeaderOption);
+ }
+ final Object indentAccessSpecifierExtraSpaces = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INDENT_ACCESS_SPECIFIER_EXTRA_SPACES);
+ if (indentAccessSpecifierExtraSpaces != null) {
+ try {
+ this.indent_access_specifier_extra_spaces = Integer.parseInt((String) indentAccessSpecifierExtraSpaces);
+ } catch (NumberFormatException e) {
+ this.indent_access_specifier_extra_spaces = 0;
+ } catch (ClassCastException e) {
+ this.indent_access_specifier_extra_spaces = 0;
+ }
+ }
+ final Object indentBodyDeclarationsCompareToAccessSpecifierOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INDENT_BODY_DECLARATIONS_COMPARE_TO_ACCESS_SPECIFIER);
+ if (indentBodyDeclarationsCompareToAccessSpecifierOption != null) {
+ this.indent_body_declarations_compare_to_access_specifier = STPDefaultCodeFormatterConstants.TRUE.equals(indentBodyDeclarationsCompareToAccessSpecifierOption);
+ }
+ final Object indentDeclarationCompareToTemplateHeaderOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INDENT_DECLARATION_COMPARE_TO_TEMPLATE_HEADER);
+ if (indentDeclarationCompareToTemplateHeaderOption != null) {
+ this.indent_declaration_compare_to_template_header = STPDefaultCodeFormatterConstants.TRUE.equals(indentDeclarationCompareToTemplateHeaderOption);
+ }
+ final Object indentBodyDeclarationsCompareToNamespaceHeaderOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INDENT_BODY_DECLARATIONS_COMPARE_TO_NAMESPACE_HEADER);
+ if (indentBodyDeclarationsCompareToNamespaceHeaderOption != null) {
+ this.indent_body_declarations_compare_to_namespace_header = STPDefaultCodeFormatterConstants.TRUE.equals(indentBodyDeclarationsCompareToNamespaceHeaderOption);
+ }
+ final Object indentBreaksCompareToCasesOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INDENT_BREAKS_COMPARE_TO_CASES);
+ if (indentBreaksCompareToCasesOption != null) {
+ this.indent_breaks_compare_to_cases = STPDefaultCodeFormatterConstants.TRUE.equals(indentBreaksCompareToCasesOption);
+ }
+ final Object indentEmptyLinesOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INDENT_EMPTY_LINES);
+ if (indentEmptyLinesOption != null) {
+ this.indent_empty_lines = STPDefaultCodeFormatterConstants.TRUE.equals(indentEmptyLinesOption);
+ }
+ final Object indentSwitchstatementsCompareToCasesOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INDENT_SWITCHSTATEMENTS_COMPARE_TO_CASES);
+ if (indentSwitchstatementsCompareToCasesOption != null) {
+ this.indent_switchstatements_compare_to_cases = STPDefaultCodeFormatterConstants.TRUE.equals(indentSwitchstatementsCompareToCasesOption);
+ }
+ final Object indentSwitchstatementsCompareToSwitchOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INDENT_SWITCHSTATEMENTS_COMPARE_TO_SWITCH);
+ if (indentSwitchstatementsCompareToSwitchOption != null) {
+ this.indent_switchstatements_compare_to_switch = STPDefaultCodeFormatterConstants.TRUE.equals(indentSwitchstatementsCompareToSwitchOption);
+ }
+ final Object indentationSizeOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INDENTATION_SIZE);
+ if (indentationSizeOption != null) {
+ try {
+ this.indentation_size = Integer.parseInt((String) indentationSizeOption);
+ } catch (NumberFormatException e) {
+ this.indentation_size = 4;
+ } catch (ClassCastException e) {
+ this.indentation_size = 4;
+ }
+ }
+ final Object insertNewLineAfterOpeningBraceInInitializerListOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_AFTER_OPENING_BRACE_IN_INITIALIZER_LIST);
+ if (insertNewLineAfterOpeningBraceInInitializerListOption != null) {
+ this.insert_new_line_after_opening_brace_in_initializer_list = IDEPlugin.INSERT.equals(insertNewLineAfterOpeningBraceInInitializerListOption);
+ }
+ final Object insertNewLineAfterTemplateDeclarationOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_AFTER_TEMPLATE_DECLARATION);
+ if (insertNewLineAfterOpeningBraceInInitializerListOption != null) {
+ this.insert_new_line_after_template_declaration = IDEPlugin.INSERT.equals(insertNewLineAfterTemplateDeclarationOption);
+ }
+ final Object insertNewLineAtEndOfFileIfMissingOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_AT_END_OF_FILE_IF_MISSING);
+ if (insertNewLineAtEndOfFileIfMissingOption != null) {
+ this.insert_new_line_at_end_of_file_if_missing = IDEPlugin.INSERT.equals(insertNewLineAtEndOfFileIfMissingOption);
+ }
+ final Object insertNewLineBeforeCatchInTryStatementOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_BEFORE_CATCH_IN_TRY_STATEMENT);
+ if (insertNewLineBeforeCatchInTryStatementOption != null) {
+ this.insert_new_line_before_catch_in_try_statement = IDEPlugin.INSERT.equals(insertNewLineBeforeCatchInTryStatementOption);
+ }
+ final Object insertNewLineBeforeClosingBraceInInitializerListOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_BEFORE_CLOSING_BRACE_IN_INITIALIZER_LIST);
+ if (insertNewLineBeforeClosingBraceInInitializerListOption != null) {
+ this.insert_new_line_before_closing_brace_in_initializer_list = IDEPlugin.INSERT.equals(insertNewLineBeforeClosingBraceInInitializerListOption);
+ }
+ final Object insertNewLineBeforeColonInConstructorInitializerListOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_BEFORE_COLON_IN_CONSTRUCTOR_INITIALIZER_LIST);
+ if (insertNewLineBeforeColonInConstructorInitializerListOption != null) {
+ this.insert_new_line_before_colon_in_constructor_initializer_list = IDEPlugin.INSERT.equals(insertNewLineBeforeColonInConstructorInitializerListOption);
+ }
+ final Object insertNewLineBeforeElseInIfStatementOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_BEFORE_ELSE_IN_IF_STATEMENT);
+ if (insertNewLineBeforeElseInIfStatementOption != null) {
+ this.insert_new_line_before_else_in_if_statement = IDEPlugin.INSERT.equals(insertNewLineBeforeElseInIfStatementOption);
+ }
+ final Object insertNewLineBeforeWhileInDoStatementOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_BEFORE_WHILE_IN_DO_STATEMENT);
+ if (insertNewLineBeforeWhileInDoStatementOption != null) {
+ this.insert_new_line_before_while_in_do_statement = IDEPlugin.INSERT.equals(insertNewLineBeforeWhileInDoStatementOption);
+ }
+ final Object insertNewLineBeforeIdentifierInFunctionDefinitionOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_BEFORE_IDENTIFIER_IN_FUNCTION_DECLARATION);
+ if (insertNewLineBeforeWhileInDoStatementOption != null) {
+ this.insert_new_line_before_identifier_in_function_declaration = IDEPlugin.INSERT.equals(insertNewLineBeforeIdentifierInFunctionDefinitionOption);
+ }
+ final Object insertNewLineInEmptyBlockOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_IN_EMPTY_BLOCK);
+ if (insertNewLineInEmptyBlockOption != null) {
+ this.insert_new_line_in_empty_block = IDEPlugin.INSERT.equals(insertNewLineInEmptyBlockOption);
+ }
+// final Object insertNewLineInEmptyMethodBodyOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_IN_EMPTY_METHOD_BODY);
+// if (insertNewLineInEmptyMethodBodyOption != null) {
+// this.insert_new_line_in_empty_method_body = IDEPlugin.INSERT.equals(insertNewLineInEmptyMethodBodyOption);
+// }
+// final Object insertNewLineInEmptyTypeDeclarationOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_IN_EMPTY_TYPE_DECLARATION);
+// if (insertNewLineInEmptyTypeDeclarationOption != null) {
+// this.insert_new_line_in_empty_type_declaration = IDEPlugin.INSERT.equals(insertNewLineInEmptyTypeDeclarationOption);
+// }
+ final Object insertSpaceAfterAssignmentOperatorOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_ASSIGNMENT_OPERATOR);
+ if (insertSpaceAfterAssignmentOperatorOption != null) {
+ this.insert_space_after_assignment_operator = IDEPlugin.INSERT.equals(insertSpaceAfterAssignmentOperatorOption);
+ }
+ final Object insertSpaceAfterBinaryOperatorOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_BINARY_OPERATOR);
+ if (insertSpaceAfterBinaryOperatorOption != null) {
+ this.insert_space_after_binary_operator = IDEPlugin.INSERT.equals(insertSpaceAfterBinaryOperatorOption);
+ }
+ final Object insertSpaceAfterClosingAngleBracketInTemplateArgumentsOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_CLOSING_ANGLE_BRACKET_IN_TEMPLATE_ARGUMENTS);
+ if (insertSpaceAfterClosingAngleBracketInTemplateArgumentsOption != null) {
+ this.insert_space_after_closing_angle_bracket_in_template_arguments = IDEPlugin.INSERT.equals(insertSpaceAfterClosingAngleBracketInTemplateArgumentsOption);
+ }
+ final Object insertSpaceAfterClosingAngleBracketInTemplateParametersOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_CLOSING_ANGLE_BRACKET_IN_TEMPLATE_PARAMETERS);
+ if (insertSpaceAfterClosingAngleBracketInTemplateParametersOption != null) {
+ this.insert_space_after_closing_angle_bracket_in_template_parameters = IDEPlugin.INSERT.equals(insertSpaceAfterClosingAngleBracketInTemplateParametersOption);
+ }
+ final Object insertSpaceAfterClosingParenInCastOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_CLOSING_PAREN_IN_CAST);
+ if (insertSpaceAfterClosingParenInCastOption != null) {
+ this.insert_space_after_closing_paren_in_cast = IDEPlugin.INSERT.equals(insertSpaceAfterClosingParenInCastOption);
+ }
+ final Object insertSpaceAfterClosingBraceInBlockOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_CLOSING_BRACE_IN_BLOCK);
+ if (insertSpaceAfterClosingBraceInBlockOption != null) {
+ this.insert_space_after_closing_brace_in_block = IDEPlugin.INSERT.equals(insertSpaceAfterClosingBraceInBlockOption);
+ }
+ final Object insertSpaceAfterColonInBaseClauseOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_COLON_IN_BASE_CLAUSE);
+ if (insertSpaceAfterColonInBaseClauseOption != null) {
+ this.insert_space_after_colon_in_base_clause = IDEPlugin.INSERT.equals(insertSpaceAfterColonInBaseClauseOption);
+ }
+ final Object insertSpaceAfterColonInCaseOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_COLON_IN_CASE);
+ if (insertSpaceAfterColonInCaseOption != null) {
+ this.insert_space_after_colon_in_case = IDEPlugin.INSERT.equals(insertSpaceAfterColonInCaseOption);
+ }
+ final Object insertSpaceAfterColonInConditionalOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_COLON_IN_CONDITIONAL);
+ if (insertSpaceAfterColonInConditionalOption != null) {
+ this.insert_space_after_colon_in_conditional = IDEPlugin.INSERT.equals(insertSpaceAfterColonInConditionalOption);
+ }
+ final Object insertSpaceAfterColonInLabeledStatementOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_COLON_IN_LABELED_STATEMENT);
+ if (insertSpaceAfterColonInLabeledStatementOption != null) {
+ this.insert_space_after_colon_in_labeled_statement = IDEPlugin.INSERT.equals(insertSpaceAfterColonInLabeledStatementOption);
+ }
+// final Object insertSpaceAfterCommaInAllocationExpressionOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_COMMA_IN_ALLOCATION_EXPRESSION);
+// if (insertSpaceAfterCommaInAllocationExpressionOption != null) {
+// this.insert_space_after_comma_in_allocation_expression = IDEPlugin.INSERT.equals(insertSpaceAfterCommaInAllocationExpressionOption);
+// }
+ final Object insertSpaceAfterCommaInInitializerListOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_COMMA_IN_INITIALIZER_LIST);
+ if (insertSpaceAfterCommaInInitializerListOption != null) {
+ this.insert_space_after_comma_in_initializer_list = IDEPlugin.INSERT.equals(insertSpaceAfterCommaInInitializerListOption);
+ }
+ final Object insertSpaceAfterCommaInEnumDeclarationsOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_COMMA_IN_ENUM_DECLARATIONS);
+ if (insertSpaceAfterCommaInEnumDeclarationsOption != null) {
+ this.insert_space_after_comma_in_enum_declarations = IDEPlugin.INSERT.equals(insertSpaceAfterCommaInEnumDeclarationsOption);
+ }
+// final Object insertSpaceAfterCommaInForInitsOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_COMMA_IN_FOR_INITS);
+// if (insertSpaceAfterCommaInForInitsOption != null) {
+// this.insert_space_after_comma_in_for_inits = IDEPlugin.INSERT.equals(insertSpaceAfterCommaInForInitsOption);
+// }
+// final Object insertSpaceAfterCommaInForIncrementsOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_COMMA_IN_FOR_INCREMENTS);
+// if (insertSpaceAfterCommaInForIncrementsOption != null) {
+// this.insert_space_after_comma_in_for_increments = IDEPlugin.INSERT.equals(insertSpaceAfterCommaInForIncrementsOption);
+// }
+ final Object insertSpaceAfterCommaInMethodInvocationArgumentsOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_COMMA_IN_METHOD_INVOCATION_ARGUMENTS);
+ if (insertSpaceAfterCommaInMethodInvocationArgumentsOption != null) {
+ this.insert_space_after_comma_in_method_invocation_arguments = IDEPlugin.INSERT.equals(insertSpaceAfterCommaInMethodInvocationArgumentsOption);
+ }
+ final Object insertSpaceAfterCommaInMethodDeclarationParametersOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_COMMA_IN_METHOD_DECLARATION_PARAMETERS);
+ if (insertSpaceAfterCommaInMethodDeclarationParametersOption != null) {
+ this.insert_space_after_comma_in_method_declaration_parameters = IDEPlugin.INSERT.equals(insertSpaceAfterCommaInMethodDeclarationParametersOption);
+ }
+ final Object insertSpaceAfterCommaInMethodDeclarationThrowsOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_COMMA_IN_METHOD_DECLARATION_THROWS);
+ if (insertSpaceAfterCommaInMethodDeclarationThrowsOption != null) {
+ this.insert_space_after_comma_in_method_declaration_throws = IDEPlugin.INSERT.equals(insertSpaceAfterCommaInMethodDeclarationThrowsOption);
+ }
+ final Object insertSpaceAfterCommaInMultipleFieldDeclarationsOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_COMMA_IN_DECLARATOR_LIST);
+ if (insertSpaceAfterCommaInMultipleFieldDeclarationsOption != null) {
+ this.insert_space_after_comma_in_declarator_list = IDEPlugin.INSERT.equals(insertSpaceAfterCommaInMultipleFieldDeclarationsOption);
+ }
+ final Object insertSpaceAfterCommaInExpressionListOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_COMMA_IN_EXPRESSION_LIST);
+ if (insertSpaceAfterCommaInExpressionListOption != null) {
+ this.insert_space_after_comma_in_expression_list = IDEPlugin.INSERT.equals(insertSpaceAfterCommaInExpressionListOption);
+ }
+ final Object insertSpaceAfterCommaInBaseTypesOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_COMMA_IN_BASE_TYPES);
+ if (insertSpaceAfterCommaInBaseTypesOption != null) {
+ this.insert_space_after_comma_in_base_types = IDEPlugin.INSERT.equals(insertSpaceAfterCommaInBaseTypesOption);
+ }
+ final Object insertSpaceAfterCommaInTemplateArgumentsOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_COMMA_IN_TEMPLATE_ARGUMENTS);
+ if (insertSpaceAfterCommaInTemplateArgumentsOption != null) {
+ this.insert_space_after_comma_in_template_arguments = IDEPlugin.INSERT.equals(insertSpaceAfterCommaInTemplateArgumentsOption);
+ }
+ final Object insertSpaceAfterCommaInTemplateParametersOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_COMMA_IN_TEMPLATE_PARAMETERS);
+ if (insertSpaceAfterCommaInTemplateParametersOption != null) {
+ this.insert_space_after_comma_in_template_parameters = IDEPlugin.INSERT.equals(insertSpaceAfterCommaInTemplateParametersOption);
+ }
+// final Object insertSpaceAfterEllipsisOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_ELLIPSIS);
+// if (insertSpaceAfterEllipsisOption != null) {
+// this.insert_space_after_ellipsis = IDEPlugin.INSERT.equals(insertSpaceAfterEllipsisOption);
+// }
+// final Object insertSpaceAfterOpeningAngleBracketInParameterizedTypeReferenceOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_OPENING_ANGLE_BRACKET_IN_PARAMETERIZED_TYPE_REFERENCE);
+// if (insertSpaceAfterOpeningAngleBracketInParameterizedTypeReferenceOption != null) {
+// this.insert_space_after_opening_angle_bracket_in_parameterized_type_reference = IDEPlugin.INSERT.equals(insertSpaceAfterOpeningAngleBracketInParameterizedTypeReferenceOption);
+// }
+ final Object insertSpaceAfterOpeningAngleBracketInTemplateArgumentsOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_OPENING_ANGLE_BRACKET_IN_TEMPLATE_ARGUMENTS);
+ if (insertSpaceAfterOpeningAngleBracketInTemplateArgumentsOption != null) {
+ this.insert_space_after_opening_angle_bracket_in_template_arguments = IDEPlugin.INSERT.equals(insertSpaceAfterOpeningAngleBracketInTemplateArgumentsOption);
+ }
+ final Object insertSpaceAfterOpeningAngleBracketInTemplateParametersOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_OPENING_ANGLE_BRACKET_IN_TEMPLATE_PARAMETERS);
+ if (insertSpaceAfterOpeningAngleBracketInTemplateParametersOption != null) {
+ this.insert_space_after_opening_angle_bracket_in_template_parameters = IDEPlugin.INSERT.equals(insertSpaceAfterOpeningAngleBracketInTemplateParametersOption);
+ }
+ final Object insertSpaceAfterOpeningBracketInArrayReferenceOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_OPENING_BRACKET);
+ if (insertSpaceAfterOpeningBracketInArrayReferenceOption != null) {
+ this.insert_space_after_opening_bracket = IDEPlugin.INSERT.equals(insertSpaceAfterOpeningBracketInArrayReferenceOption);
+ }
+ final Object insertSpaceAfterOpeningBraceInInitializerListOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_OPENING_BRACE_IN_INITIALIZER_LIST);
+ if (insertSpaceAfterOpeningBraceInInitializerListOption != null) {
+ this.insert_space_after_opening_brace_in_initializer_list = IDEPlugin.INSERT.equals(insertSpaceAfterOpeningBraceInInitializerListOption);
+ }
+ final Object insertSpaceAfterOpeningParenInCastOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_OPENING_PAREN_IN_CAST);
+ if (insertSpaceAfterOpeningParenInCastOption != null) {
+ this.insert_space_after_opening_paren_in_cast = IDEPlugin.INSERT.equals(insertSpaceAfterOpeningParenInCastOption);
+ }
+ final Object insertSpaceAfterOpeningParenInCatchOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_OPENING_PAREN_IN_CATCH);
+ if (insertSpaceAfterOpeningParenInCatchOption != null) {
+ this.insert_space_after_opening_paren_in_catch = IDEPlugin.INSERT.equals(insertSpaceAfterOpeningParenInCatchOption);
+ }
+ final Object insertSpaceAfterOpeningParenInForOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_OPENING_PAREN_IN_FOR);
+ if (insertSpaceAfterOpeningParenInForOption != null) {
+ this.insert_space_after_opening_paren_in_for = IDEPlugin.INSERT.equals(insertSpaceAfterOpeningParenInForOption);
+ }
+ final Object insertSpaceAfterOpeningParenInIfOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_OPENING_PAREN_IN_IF);
+ if (insertSpaceAfterOpeningParenInIfOption != null) {
+ this.insert_space_after_opening_paren_in_if = IDEPlugin.INSERT.equals(insertSpaceAfterOpeningParenInIfOption);
+ }
+ final Object insertSpaceAfterOpeningParenInMethodDeclarationOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_OPENING_PAREN_IN_METHOD_DECLARATION);
+ if (insertSpaceAfterOpeningParenInMethodDeclarationOption != null) {
+ this.insert_space_after_opening_paren_in_method_declaration = IDEPlugin.INSERT.equals(insertSpaceAfterOpeningParenInMethodDeclarationOption);
+ }
+ final Object insertSpaceAfterOpeningParenInExceptionSpecificationOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_OPENING_PAREN_IN_EXCEPTION_SPECIFICATION);
+ if (insertSpaceAfterOpeningParenInExceptionSpecificationOption != null) {
+ this.insert_space_after_opening_paren_in_exception_specification = IDEPlugin.INSERT.equals(insertSpaceAfterOpeningParenInExceptionSpecificationOption);
+ }
+ final Object insertSpaceAfterOpeningParenInMethodInvocationOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_OPENING_PAREN_IN_METHOD_INVOCATION);
+ if (insertSpaceAfterOpeningParenInMethodInvocationOption != null) {
+ this.insert_space_after_opening_paren_in_method_invocation = IDEPlugin.INSERT.equals(insertSpaceAfterOpeningParenInMethodInvocationOption);
+ }
+ final Object insertSpaceAfterOpeningParenInParenthesizedExpressionOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_OPENING_PAREN_IN_PARENTHESIZED_EXPRESSION);
+ if (insertSpaceAfterOpeningParenInParenthesizedExpressionOption != null) {
+ this.insert_space_after_opening_paren_in_parenthesized_expression = IDEPlugin.INSERT.equals(insertSpaceAfterOpeningParenInParenthesizedExpressionOption);
+ }
+ final Object insertSpaceAfterOpeningParenInSwitchOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_OPENING_PAREN_IN_SWITCH);
+ if (insertSpaceAfterOpeningParenInSwitchOption != null) {
+ this.insert_space_after_opening_paren_in_switch = IDEPlugin.INSERT.equals(insertSpaceAfterOpeningParenInSwitchOption);
+ }
+ final Object insertSpaceAfterOpeningParenInWhileOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_OPENING_PAREN_IN_WHILE);
+ if (insertSpaceAfterOpeningParenInWhileOption != null) {
+ this.insert_space_after_opening_paren_in_while = IDEPlugin.INSERT.equals(insertSpaceAfterOpeningParenInWhileOption);
+ }
+ final Object insertSpaceAfterPostfixOperatorOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_POSTFIX_OPERATOR);
+ if (insertSpaceAfterPostfixOperatorOption != null) {
+ this.insert_space_after_postfix_operator = IDEPlugin.INSERT.equals(insertSpaceAfterPostfixOperatorOption);
+ }
+ final Object insertSpaceAfterPrefixOperatorOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_PREFIX_OPERATOR);
+ if (insertSpaceAfterPrefixOperatorOption != null) {
+ this.insert_space_after_prefix_operator = IDEPlugin.INSERT.equals(insertSpaceAfterPrefixOperatorOption);
+ }
+ final Object insertSpaceAfterQuestionInConditionalOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_QUESTION_IN_CONDITIONAL);
+ if (insertSpaceAfterQuestionInConditionalOption != null) {
+ this.insert_space_after_question_in_conditional = IDEPlugin.INSERT.equals(insertSpaceAfterQuestionInConditionalOption);
+ }
+ final Object insertSpaceAfterSemicolonInForOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_SEMICOLON_IN_FOR);
+ if (insertSpaceAfterSemicolonInForOption != null) {
+ this.insert_space_after_semicolon_in_for = IDEPlugin.INSERT.equals(insertSpaceAfterSemicolonInForOption);
+ }
+ final Object insertSpaceAfterUnaryOperatorOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_UNARY_OPERATOR);
+ if (insertSpaceAfterUnaryOperatorOption != null) {
+ this.insert_space_after_unary_operator = IDEPlugin.INSERT.equals(insertSpaceAfterUnaryOperatorOption);
+ }
+ final Object insertSpaceBeforeAssignmentOperatorOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_ASSIGNMENT_OPERATOR);
+ if (insertSpaceBeforeAssignmentOperatorOption != null) {
+ this.insert_space_before_assignment_operator = IDEPlugin.INSERT.equals(insertSpaceBeforeAssignmentOperatorOption);
+ }
+ final Object insertSpaceBeforeBinaryOperatorOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_BINARY_OPERATOR);
+ if (insertSpaceBeforeBinaryOperatorOption != null) {
+ this.insert_space_before_binary_operator = IDEPlugin.INSERT.equals(insertSpaceBeforeBinaryOperatorOption);
+ }
+ final Object insertSpaceBeforeClosingAngleBracketInTemplateArgumentsOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_CLOSING_ANGLE_BRACKET_IN_TEMPLATE_ARGUMENTS);
+ if (insertSpaceBeforeClosingAngleBracketInTemplateArgumentsOption != null) {
+ this.insert_space_before_closing_angle_bracket_in_template_arguments = IDEPlugin.INSERT.equals(insertSpaceBeforeClosingAngleBracketInTemplateArgumentsOption);
+ }
+ final Object insertSpaceBeforeClosingAngleBracketInTemplateParametersOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_CLOSING_ANGLE_BRACKET_IN_TEMPLATE_PARAMETERS);
+ if (insertSpaceBeforeClosingAngleBracketInTemplateParametersOption != null) {
+ this.insert_space_before_closing_angle_bracket_in_template_parameters = IDEPlugin.INSERT.equals(insertSpaceBeforeClosingAngleBracketInTemplateParametersOption);
+ }
+ final Object insertSpaceBeforeClosingBraceInInitializerListOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_CLOSING_BRACE_IN_INITIALIZER_LIST);
+ if (insertSpaceBeforeClosingBraceInInitializerListOption != null) {
+ this.insert_space_before_closing_brace_in_initializer_list = IDEPlugin.INSERT.equals(insertSpaceBeforeClosingBraceInInitializerListOption);
+ }
+ final Object insertSpaceBeforeClosingBracketInArrayReferenceOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_CLOSING_BRACKET);
+ if (insertSpaceBeforeClosingBracketInArrayReferenceOption != null) {
+ this.insert_space_before_closing_bracket = IDEPlugin.INSERT.equals(insertSpaceBeforeClosingBracketInArrayReferenceOption);
+ }
+ final Object insertSpaceBeforeClosingParenInCastOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_CLOSING_PAREN_IN_CAST);
+ if (insertSpaceBeforeClosingParenInCastOption != null) {
+ this.insert_space_before_closing_paren_in_cast = IDEPlugin.INSERT.equals(insertSpaceBeforeClosingParenInCastOption);
+ }
+ final Object insertSpaceBeforeClosingParenInCatchOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_CLOSING_PAREN_IN_CATCH);
+ if (insertSpaceBeforeClosingParenInCatchOption != null) {
+ this.insert_space_before_closing_paren_in_catch = IDEPlugin.INSERT.equals(insertSpaceBeforeClosingParenInCatchOption);
+ }
+ final Object insertSpaceBeforeClosingParenInForOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_CLOSING_PAREN_IN_FOR);
+ if (insertSpaceBeforeClosingParenInForOption != null) {
+ this.insert_space_before_closing_paren_in_for = IDEPlugin.INSERT.equals(insertSpaceBeforeClosingParenInForOption);
+ }
+ final Object insertSpaceBeforeClosingParenInIfOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_CLOSING_PAREN_IN_IF);
+ if (insertSpaceBeforeClosingParenInIfOption != null) {
+ this.insert_space_before_closing_paren_in_if = IDEPlugin.INSERT.equals(insertSpaceBeforeClosingParenInIfOption);
+ }
+ final Object insertSpaceBeforeClosingParenInMethodDeclarationOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_CLOSING_PAREN_IN_METHOD_DECLARATION);
+ if (insertSpaceBeforeClosingParenInMethodDeclarationOption != null) {
+ this.insert_space_before_closing_paren_in_method_declaration = IDEPlugin.INSERT.equals(insertSpaceBeforeClosingParenInMethodDeclarationOption);
+ }
+ final Object insertSpaceBeforeClosingParenInExceptionSpecificationOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_CLOSING_PAREN_IN_EXCEPTION_SPECIFICATION);
+ if (insertSpaceBeforeClosingParenInExceptionSpecificationOption != null) {
+ this.insert_space_before_closing_paren_in_exception_specification = IDEPlugin.INSERT.equals(insertSpaceBeforeClosingParenInExceptionSpecificationOption);
+ }
+ final Object insertSpaceBeforeClosingParenInMethodInvocationOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_CLOSING_PAREN_IN_METHOD_INVOCATION);
+ if (insertSpaceBeforeClosingParenInMethodInvocationOption != null) {
+ this.insert_space_before_closing_paren_in_method_invocation = IDEPlugin.INSERT.equals(insertSpaceBeforeClosingParenInMethodInvocationOption);
+ }
+ final Object insertSpaceBeforeClosingParenInParenthesizedExpressionOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_CLOSING_PAREN_IN_PARENTHESIZED_EXPRESSION);
+ if (insertSpaceBeforeClosingParenInParenthesizedExpressionOption != null) {
+ this.insert_space_before_closing_paren_in_parenthesized_expression = IDEPlugin.INSERT.equals(insertSpaceBeforeClosingParenInParenthesizedExpressionOption);
+ }
+ final Object insertSpaceBeforeClosingParenInSwitchOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_CLOSING_PAREN_IN_SWITCH);
+ if (insertSpaceBeforeClosingParenInSwitchOption != null) {
+ this.insert_space_before_closing_paren_in_switch = IDEPlugin.INSERT.equals(insertSpaceBeforeClosingParenInSwitchOption);
+ }
+ final Object insertSpaceBeforeClosingParenInWhileOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_CLOSING_PAREN_IN_WHILE);
+ if (insertSpaceBeforeClosingParenInWhileOption != null) {
+ this.insert_space_before_closing_paren_in_while = IDEPlugin.INSERT.equals(insertSpaceBeforeClosingParenInWhileOption);
+ }
+ final Object insertSpaceBeforeColonInCaseOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_COLON_IN_CASE);
+ final Object insertSpaceBeforeColonInBaseClauseOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_COLON_IN_BASE_CLAUSE);
+ if (insertSpaceBeforeColonInBaseClauseOption != null) {
+ this.insert_space_before_colon_in_base_clause = IDEPlugin.INSERT.equals(insertSpaceBeforeColonInBaseClauseOption);
+ }
+ if (insertSpaceBeforeColonInCaseOption != null) {
+ this.insert_space_before_colon_in_case = IDEPlugin.INSERT.equals(insertSpaceBeforeColonInCaseOption);
+ }
+ final Object insertSpaceBeforeColonInConditionalOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_COLON_IN_CONDITIONAL);
+ if (insertSpaceBeforeColonInConditionalOption != null) {
+ this.insert_space_before_colon_in_conditional = IDEPlugin.INSERT.equals(insertSpaceBeforeColonInConditionalOption);
+ }
+ final Object insertSpaceBeforeColonInDefaultOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_COLON_IN_DEFAULT);
+ if (insertSpaceBeforeColonInDefaultOption != null) {
+ this.insert_space_before_colon_in_default = IDEPlugin.INSERT.equals(insertSpaceBeforeColonInDefaultOption);
+ }
+ final Object insertSpaceBeforeColonInLabeledStatementOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_COLON_IN_LABELED_STATEMENT);
+ if (insertSpaceBeforeColonInLabeledStatementOption != null) {
+ this.insert_space_before_colon_in_labeled_statement = IDEPlugin.INSERT.equals(insertSpaceBeforeColonInLabeledStatementOption);
+ }
+// final Object insertSpaceBeforeCommaInAllocationExpressionOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_COMMA_IN_ALLOCATION_EXPRESSION);
+// if (insertSpaceBeforeCommaInAllocationExpressionOption != null) {
+// this.insert_space_before_comma_in_allocation_expression = IDEPlugin.INSERT.equals(insertSpaceBeforeCommaInAllocationExpressionOption);
+// }
+ final Object insertSpaceBeforeCommaInInitializerListOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_COMMA_IN_INITIALIZER_LIST);
+ if (insertSpaceBeforeCommaInInitializerListOption != null) {
+ this.insert_space_before_comma_in_initializer_list = IDEPlugin.INSERT.equals(insertSpaceBeforeCommaInInitializerListOption);
+ }
+ final Object insertSpaceBeforeCommaInEnumDeclarationsOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_COMMA_IN_ENUM_DECLARATIONS);
+ if (insertSpaceBeforeCommaInEnumDeclarationsOption != null) {
+ this.insert_space_before_comma_in_enum_declarations = IDEPlugin.INSERT.equals(insertSpaceBeforeCommaInEnumDeclarationsOption);
+ }
+// final Object insertSpaceBeforeCommaInForInitsOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_COMMA_IN_FOR_INITS);
+// if (insertSpaceBeforeCommaInForInitsOption != null) {
+// this.insert_space_before_comma_in_for_inits = IDEPlugin.INSERT.equals(insertSpaceBeforeCommaInForInitsOption);
+// }
+// final Object insertSpaceBeforeCommaInForIncrementsOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_COMMA_IN_FOR_INCREMENTS);
+// if (insertSpaceBeforeCommaInForIncrementsOption != null) {
+// this.insert_space_before_comma_in_for_increments = IDEPlugin.INSERT.equals(insertSpaceBeforeCommaInForIncrementsOption);
+// }
+ final Object insertSpaceBeforeCommaInMethodInvocationArgumentsOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_COMMA_IN_METHOD_INVOCATION_ARGUMENTS);
+ if (insertSpaceBeforeCommaInMethodInvocationArgumentsOption != null) {
+ this.insert_space_before_comma_in_method_invocation_arguments = IDEPlugin.INSERT.equals(insertSpaceBeforeCommaInMethodInvocationArgumentsOption);
+ }
+ final Object insertSpaceBeforeCommaInMethodDeclarationParametersOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_COMMA_IN_METHOD_DECLARATION_PARAMETERS);
+ if (insertSpaceBeforeCommaInMethodDeclarationParametersOption != null) {
+ this.insert_space_before_comma_in_method_declaration_parameters = IDEPlugin.INSERT.equals(insertSpaceBeforeCommaInMethodDeclarationParametersOption);
+ }
+ final Object insertSpaceBeforeCommaInMethodDeclarationThrowsOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_COMMA_IN_METHOD_DECLARATION_THROWS);
+ if (insertSpaceBeforeCommaInMethodDeclarationThrowsOption != null) {
+ this.insert_space_before_comma_in_method_declaration_throws = IDEPlugin.INSERT.equals(insertSpaceBeforeCommaInMethodDeclarationThrowsOption);
+ }
+ final Object insertSpaceBeforeCommaInMultipleFieldDeclarationsOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_COMMA_IN_DECLARATOR_LIST);
+ if (insertSpaceBeforeCommaInMultipleFieldDeclarationsOption != null) {
+ this.insert_space_before_comma_in_declarator_list = IDEPlugin.INSERT.equals(insertSpaceBeforeCommaInMultipleFieldDeclarationsOption);
+ }
+ final Object insertSpaceBeforeCommaInMultipleLocalDeclarationsOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_COMMA_IN_EXPRESSION_LIST);
+ if (insertSpaceBeforeCommaInMultipleLocalDeclarationsOption != null) {
+ this.insert_space_before_comma_in_expression_list = IDEPlugin.INSERT.equals(insertSpaceBeforeCommaInMultipleLocalDeclarationsOption);
+ }
+ final Object insertSpaceBeforeCommaInBaseTypesOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_COMMA_IN_BASE_TYPES);
+ if (insertSpaceBeforeCommaInBaseTypesOption != null) {
+ this.insert_space_before_comma_in_base_types = IDEPlugin.INSERT.equals(insertSpaceBeforeCommaInBaseTypesOption);
+ }
+ final Object insertSpaceBeforeCommaInTemplateArgumentsOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_COMMA_IN_TEMPLATE_ARGUMENTS);
+ if (insertSpaceBeforeCommaInTemplateArgumentsOption != null) {
+ this.insert_space_before_comma_in_template_arguments = IDEPlugin.INSERT.equals(insertSpaceBeforeCommaInTemplateArgumentsOption);
+ }
+ final Object insertSpaceBeforeCommaInTemplateParametersOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_COMMA_IN_TEMPLATE_PARAMETERS);
+ if (insertSpaceBeforeCommaInTemplateParametersOption != null) {
+ this.insert_space_before_comma_in_template_parameters = IDEPlugin.INSERT.equals(insertSpaceBeforeCommaInTemplateParametersOption);
+ }
+// final Object insertSpaceBeforeEllipsisOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_ELLIPSIS);
+// if (insertSpaceBeforeEllipsisOption != null) {
+// this.insert_space_before_ellipsis = IDEPlugin.INSERT.equals(insertSpaceBeforeEllipsisOption);
+// }
+ final Object insertSpaceBeforeOpeningAngleBrackerInTemplateArgumentsOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_OPENING_ANGLE_BRACKET_IN_TEMPLATE_ARGUMENTS);
+ if (insertSpaceBeforeOpeningAngleBrackerInTemplateArgumentsOption != null) {
+ this.insert_space_before_opening_angle_bracket_in_template_arguments = IDEPlugin.INSERT.equals(insertSpaceBeforeOpeningAngleBrackerInTemplateArgumentsOption);
+ }
+ final Object insertSpaceBeforeOpeningAngleBrackerInTemplateParametersOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_OPENING_ANGLE_BRACKET_IN_TEMPLATE_PARAMETERS);
+ if (insertSpaceBeforeOpeningAngleBrackerInTemplateParametersOption != null) {
+ this.insert_space_before_opening_angle_bracket_in_template_parameters = IDEPlugin.INSERT.equals(insertSpaceBeforeOpeningAngleBrackerInTemplateParametersOption);
+ }
+ final Object insertSpaceBeforeOpeningBraceInInitializerListOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_OPENING_BRACE_IN_INITIALIZER_LIST);
+ if (insertSpaceBeforeOpeningBraceInInitializerListOption != null) {
+ this.insert_space_before_opening_brace_in_initializer_list = IDEPlugin.INSERT.equals(insertSpaceBeforeOpeningBraceInInitializerListOption);
+ }
+ final Object insertSpaceBeforeOpeningBraceInBlockOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_OPENING_BRACE_IN_BLOCK);
+ if (insertSpaceBeforeOpeningBraceInBlockOption != null) {
+ this.insert_space_before_opening_brace_in_block = IDEPlugin.INSERT.equals(insertSpaceBeforeOpeningBraceInBlockOption);
+ }
+ final Object insertSpaceBeforeOpeningBraceInMethodDeclarationOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_OPENING_BRACE_IN_METHOD_DECLARATION);
+ if (insertSpaceBeforeOpeningBraceInMethodDeclarationOption != null) {
+ this.insert_space_before_opening_brace_in_method_declaration = IDEPlugin.INSERT.equals(insertSpaceBeforeOpeningBraceInMethodDeclarationOption);
+ }
+ final Object insertSpaceBeforeOpeningBraceInTypeDeclarationOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_OPENING_BRACE_IN_TYPE_DECLARATION);
+ if (insertSpaceBeforeOpeningBraceInTypeDeclarationOption != null) {
+ this.insert_space_before_opening_brace_in_type_declaration = IDEPlugin.INSERT.equals(insertSpaceBeforeOpeningBraceInTypeDeclarationOption);
+ }
+ final Object insertSpaceBeforeOpeningBraceInNamespaceDeclarationOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_OPENING_BRACE_IN_NAMESPACE_DECLARATION);
+ if (insertSpaceBeforeOpeningBraceInNamespaceDeclarationOption != null) {
+ this.insert_space_before_opening_brace_in_namespace_declaration = IDEPlugin.INSERT.equals(insertSpaceBeforeOpeningBraceInNamespaceDeclarationOption);
+ }
+ final Object insertSpaceBeforeOpeningBracketInArrayReferenceOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_OPENING_BRACKET);
+ if (insertSpaceBeforeOpeningBracketInArrayReferenceOption != null) {
+ this.insert_space_before_opening_bracket = IDEPlugin.INSERT.equals(insertSpaceBeforeOpeningBracketInArrayReferenceOption);
+ }
+ final Object insertSpaceBeforeOpeningParenInCatchOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_OPENING_PAREN_IN_CATCH);
+ if (insertSpaceBeforeOpeningParenInCatchOption != null) {
+ this.insert_space_before_opening_paren_in_catch = IDEPlugin.INSERT.equals(insertSpaceBeforeOpeningParenInCatchOption);
+ }
+ final Object insertSpaceBeforeOpeningParenInForOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_OPENING_PAREN_IN_FOR);
+ if (insertSpaceBeforeOpeningParenInForOption != null) {
+ this.insert_space_before_opening_paren_in_for = IDEPlugin.INSERT.equals(insertSpaceBeforeOpeningParenInForOption);
+ }
+ final Object insertSpaceBeforeOpeningParenInIfOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_OPENING_PAREN_IN_IF);
+ if (insertSpaceBeforeOpeningParenInIfOption != null) {
+ this.insert_space_before_opening_paren_in_if = IDEPlugin.INSERT.equals(insertSpaceBeforeOpeningParenInIfOption);
+ }
+ final Object insertSpaceBeforeOpeningParenInMethodInvocationOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_OPENING_PAREN_IN_METHOD_INVOCATION);
+ if (insertSpaceBeforeOpeningParenInMethodInvocationOption != null) {
+ this.insert_space_before_opening_paren_in_method_invocation = IDEPlugin.INSERT.equals(insertSpaceBeforeOpeningParenInMethodInvocationOption);
+ }
+ final Object insertSpaceBeforeOpeningParenInMethodDeclarationOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_OPENING_PAREN_IN_METHOD_DECLARATION);
+ if (insertSpaceBeforeOpeningParenInMethodDeclarationOption != null) {
+ this.insert_space_before_opening_paren_in_method_declaration = IDEPlugin.INSERT.equals(insertSpaceBeforeOpeningParenInMethodDeclarationOption);
+ }
+ final Object insertSpaceBeforeOpeningParenInExceptionSpecificationOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_OPENING_PAREN_IN_EXCEPTION_SPECIFICATION);
+ if (insertSpaceBeforeOpeningParenInExceptionSpecificationOption != null) {
+ this.insert_space_before_opening_paren_in_exception_specification = IDEPlugin.INSERT.equals(insertSpaceBeforeOpeningParenInExceptionSpecificationOption);
+ }
+ final Object insertSpaceBeforeOpeningParenInSwitchOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_OPENING_PAREN_IN_SWITCH);
+ if (insertSpaceBeforeOpeningParenInSwitchOption != null) {
+ this.insert_space_before_opening_paren_in_switch = IDEPlugin.INSERT.equals(insertSpaceBeforeOpeningParenInSwitchOption);
+ }
+ final Object insertSpaceBeforeOpeningBraceInSwitchOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_OPENING_BRACE_IN_SWITCH);
+ if (insertSpaceBeforeOpeningBraceInSwitchOption != null) {
+ this.insert_space_before_opening_brace_in_switch = IDEPlugin.INSERT.equals(insertSpaceBeforeOpeningBraceInSwitchOption);
+ }
+ final Object insertSpaceBeforeOpeningParenInParenthesizedExpressionOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_OPENING_PAREN_IN_PARENTHESIZED_EXPRESSION);
+ if (insertSpaceBeforeOpeningParenInParenthesizedExpressionOption != null) {
+ this.insert_space_before_opening_paren_in_parenthesized_expression = IDEPlugin.INSERT.equals(insertSpaceBeforeOpeningParenInParenthesizedExpressionOption);
+ }
+ final Object insertSpaceBeforeOpeningParenInWhileOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_OPENING_PAREN_IN_WHILE);
+ if (insertSpaceBeforeOpeningParenInWhileOption != null) {
+ this.insert_space_before_opening_paren_in_while = IDEPlugin.INSERT.equals(insertSpaceBeforeOpeningParenInWhileOption);
+ }
+// final Object insertSpaceBeforeParenthesizedExpressionInReturnOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_PARENTHESIZED_EXPRESSION_IN_RETURN);
+// if (insertSpaceBeforeParenthesizedExpressionInReturnOption != null) {
+// this.insert_space_before_parenthesized_expression_in_return = IDEPlugin.INSERT.equals(insertSpaceBeforeParenthesizedExpressionInReturnOption);
+// }
+ final Object insertSpaceBeforePostfixOperatorOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_POSTFIX_OPERATOR);
+ if (insertSpaceBeforePostfixOperatorOption != null) {
+ this.insert_space_before_postfix_operator = IDEPlugin.INSERT.equals(insertSpaceBeforePostfixOperatorOption);
+ }
+ final Object insertSpaceBeforePrefixOperatorOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_PREFIX_OPERATOR);
+ if (insertSpaceBeforePrefixOperatorOption != null) {
+ this.insert_space_before_prefix_operator = IDEPlugin.INSERT.equals(insertSpaceBeforePrefixOperatorOption);
+ }
+ final Object insertSpaceBeforeQuestionInConditionalOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_QUESTION_IN_CONDITIONAL);
+ if (insertSpaceBeforeQuestionInConditionalOption != null) {
+ this.insert_space_before_question_in_conditional = IDEPlugin.INSERT.equals(insertSpaceBeforeQuestionInConditionalOption);
+ }
+ final Object insertSpaceBeforeSemicolonOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_SEMICOLON);
+ if (insertSpaceBeforeSemicolonOption != null) {
+ this.insert_space_before_semicolon = IDEPlugin.INSERT.equals(insertSpaceBeforeSemicolonOption);
+ }
+ final Object insertSpaceBeforeSemicolonInForOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_SEMICOLON_IN_FOR);
+ if (insertSpaceBeforeSemicolonInForOption != null) {
+ this.insert_space_before_semicolon_in_for = IDEPlugin.INSERT.equals(insertSpaceBeforeSemicolonInForOption);
+ }
+ final Object insertSpaceBeforeUnaryOperatorOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_UNARY_OPERATOR);
+ if (insertSpaceBeforeUnaryOperatorOption != null) {
+ this.insert_space_before_unary_operator = IDEPlugin.INSERT.equals(insertSpaceBeforeUnaryOperatorOption);
+ }
+ final Object insertSpaceBetweenEmptyBracesInInitializerListOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BETWEEN_EMPTY_BRACES_IN_INITIALIZER_LIST);
+ if (insertSpaceBetweenEmptyBracesInInitializerListOption != null) {
+ this.insert_space_between_empty_braces_in_initializer_list = IDEPlugin.INSERT.equals(insertSpaceBetweenEmptyBracesInInitializerListOption);
+ }
+ final Object insertSpaceBetweenEmptyBracketsOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BETWEEN_EMPTY_BRACKETS);
+ if (insertSpaceBetweenEmptyBracketsOption != null) {
+ this.insert_space_between_empty_brackets = IDEPlugin.INSERT.equals(insertSpaceBetweenEmptyBracketsOption);
+ }
+ final Object insertSpaceBetweenEmptyParensInMethodDeclarationOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BETWEEN_EMPTY_PARENS_IN_METHOD_DECLARATION);
+ if (insertSpaceBetweenEmptyParensInMethodDeclarationOption != null) {
+ this.insert_space_between_empty_parens_in_method_declaration = IDEPlugin.INSERT.equals(insertSpaceBetweenEmptyParensInMethodDeclarationOption);
+ }
+ final Object insertSpaceBetweenEmptyParensInMethodInvocationOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BETWEEN_EMPTY_PARENS_IN_METHOD_INVOCATION);
+ if (insertSpaceBetweenEmptyParensInMethodInvocationOption != null) {
+ this.insert_space_between_empty_parens_in_method_invocation = IDEPlugin.INSERT.equals(insertSpaceBetweenEmptyParensInMethodInvocationOption);
+ }
+ final Object insertSpaceBetweenEmptyParensInExceptionSpecificationOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BETWEEN_EMPTY_PARENS_IN_EXCEPTION_SPECIFICATION);
+ if (insertSpaceBetweenEmptyParensInExceptionSpecificationOption != null) {
+ this.insert_space_between_empty_parens_in_exception_specification = IDEPlugin.INSERT.equals(insertSpaceBetweenEmptyParensInExceptionSpecificationOption);
+ }
+ final Object compactElseIfOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_COMPACT_ELSE_IF);
+ if (compactElseIfOption != null) {
+ this.compact_else_if = STPDefaultCodeFormatterConstants.TRUE.equals(compactElseIfOption);
+ }
+ final Object keepGuardianClauseOnOneLineOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_KEEP_GUARDIAN_CLAUSE_ON_ONE_LINE);
+ if (keepGuardianClauseOnOneLineOption != null) {
+ this.keep_guardian_clause_on_one_line = STPDefaultCodeFormatterConstants.TRUE.equals(keepGuardianClauseOnOneLineOption);
+ }
+ final Object keepElseStatementOnSameLineOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_KEEP_ELSE_STATEMENT_ON_SAME_LINE);
+ if (keepElseStatementOnSameLineOption != null) {
+ this.keep_else_statement_on_same_line = STPDefaultCodeFormatterConstants.TRUE.equals(keepElseStatementOnSameLineOption);
+ }
+ final Object keepEmptyInitializerListOnOneLineOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_KEEP_EMPTY_INITIALIZER_LIST_ON_ONE_LINE);
+ if (keepEmptyInitializerListOnOneLineOption != null) {
+ this.keep_empty_initializer_list_on_one_line = STPDefaultCodeFormatterConstants.TRUE.equals(keepEmptyInitializerListOnOneLineOption);
+ }
+ final Object keepSimpleIfOnOneLineOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_KEEP_SIMPLE_IF_ON_ONE_LINE);
+ if (keepSimpleIfOnOneLineOption != null) {
+ this.keep_simple_if_on_one_line = STPDefaultCodeFormatterConstants.TRUE.equals(keepSimpleIfOnOneLineOption);
+ }
+ final Object keepThenStatementOnSameLineOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_KEEP_THEN_STATEMENT_ON_SAME_LINE);
+ if (keepThenStatementOnSameLineOption != null) {
+ this.keep_then_statement_on_same_line = STPDefaultCodeFormatterConstants.TRUE.equals(keepThenStatementOnSameLineOption);
+ }
+ final Object numberOfEmptyLinesToPreserveOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_NUMBER_OF_EMPTY_LINES_TO_PRESERVE);
+ if (numberOfEmptyLinesToPreserveOption != null) {
+ try {
+ this.number_of_empty_lines_to_preserve = Integer.parseInt((String) numberOfEmptyLinesToPreserveOption);
+ } catch (NumberFormatException e) {
+ this.number_of_empty_lines_to_preserve = 0;
+ } catch (ClassCastException e) {
+ this.number_of_empty_lines_to_preserve = 0;
+ }
+ }
+ final Object joinWrappedLinesOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_JOIN_WRAPPED_LINES);
+ if (joinWrappedLinesOption != null) {
+ this.join_wrapped_lines = STPDefaultCodeFormatterConstants.TRUE.equals(joinWrappedLinesOption);
+ }
+ final Object putEmptyStatementOnNewLineOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_PUT_EMPTY_STATEMENT_ON_NEW_LINE);
+ if (putEmptyStatementOnNewLineOption != null) {
+ this.put_empty_statement_on_new_line = STPDefaultCodeFormatterConstants.TRUE.equals(putEmptyStatementOnNewLineOption);
+ }
+ final Object tabSizeOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_TAB_SIZE);
+ if (tabSizeOption != null) {
+ try {
+ this.tab_size = Integer.parseInt((String) tabSizeOption);
+ } catch (NumberFormatException e) {
+ this.tab_size = 4;
+ } catch (ClassCastException e) {
+ this.tab_size = 4;
+ }
+ }
+ final Object useTabsOnlyForLeadingIndentationsOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_USE_TABS_ONLY_FOR_LEADING_INDENTATIONS);
+ if (useTabsOnlyForLeadingIndentationsOption != null) {
+ this.use_tabs_only_for_leading_indentations = STPDefaultCodeFormatterConstants.TRUE.equals(useTabsOnlyForLeadingIndentationsOption);
+ }
+ final Object pageWidthOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_LINE_SPLIT);
+ if (pageWidthOption != null) {
+ try {
+ this.page_width = Integer.parseInt((String) pageWidthOption);
+ } catch (NumberFormatException e) {
+ this.page_width = 80;
+ } catch (ClassCastException e) {
+ this.page_width = 80;
+ }
+ }
+ final Object useTabOption = settings.get(STPDefaultCodeFormatterConstants.FORMATTER_TAB_CHAR);
+ if (useTabOption != null) {
+ if (IDEPlugin.TAB.equals(useTabOption)) {
+ this.tab_char = TAB;
+ } else if (IDEPlugin.SPACE.equals(useTabOption)) {
+ this.tab_char = SPACE;
+ } else {
+ this.tab_char = MIXED;
+ }
+ }
+ }
+
+ public void setDefaultSettings() {
+// this.alignment_for_arguments_in_allocation_expression = STPAlignment.M_COMPACT_SPLIT;
+ this.alignment_for_arguments_in_method_invocation = STPAlignment.M_COMPACT_SPLIT;
+ this.alignment_for_assignment = STPAlignment.M_COMPACT_SPLIT;
+ this.alignment_for_base_clause_in_type_declaration = STPAlignment.M_NEXT_PER_LINE_SPLIT;
+ this.alignment_for_binary_expression = STPAlignment.M_COMPACT_SPLIT;
+ this.alignment_for_compact_if = STPAlignment.M_COMPACT_SPLIT;
+ this.alignment_for_conditional_expression = STPAlignment.M_COMPACT_FIRST_BREAK_SPLIT | STPAlignment.M_INDENT_ON_COLUMN;
+ this.alignment_for_conditional_expression_chain = STPAlignment.M_COMPACT_SPLIT | STPAlignment.M_INDENT_ON_COLUMN;
+ this.alignment_for_declarator_list = STPAlignment.M_COMPACT_SPLIT;
+ this.alignment_for_enumerator_list = STPAlignment.M_ONE_PER_LINE_SPLIT;
+ this.alignment_for_expressions_in_initializer_list = STPAlignment.M_COMPACT_SPLIT;
+ this.alignment_for_member_access = STPAlignment.M_NO_ALIGNMENT;
+ this.alignment_for_overloaded_left_shift_chain = STPAlignment.M_COMPACT_SPLIT;
+ this.alignment_for_parameters_in_method_declaration = STPAlignment.M_COMPACT_SPLIT;
+// this.alignment_for_selector_in_method_invocation = STPAlignment.M_COMPACT_SPLIT;
+ this.alignment_for_throws_clause_in_method_declaration = STPAlignment.M_COMPACT_SPLIT;
+// this.align_type_members_on_columns = false;
+// this.blank_lines_after_includes = 1;
+// this.blank_lines_before_field = 1;
+// this.blank_lines_before_first_class_body_declaration = 0;
+// this.blank_lines_before_includes = 1;
+// this.blank_lines_before_member_type = 1;
+// this.blank_lines_before_method = 1;
+// this.blank_lines_before_new_chunk = 1;
+// this.blank_lines_between_type_declarations = 1;
+// this.blank_lines_at_beginning_of_method_body = 0;
+ this.brace_position_for_block = STPDefaultCodeFormatterConstants.END_OF_LINE;
+ this.brace_position_for_block_in_case = STPDefaultCodeFormatterConstants.END_OF_LINE;
+// this.brace_position_for_enum_declaration = STPDefaultCodeFormatterConstants.END_OF_LINE;
+ this.brace_position_for_initializer_list = STPDefaultCodeFormatterConstants.END_OF_LINE;
+ this.brace_position_for_method_declaration = STPDefaultCodeFormatterConstants.END_OF_LINE;
+ this.brace_position_for_namespace_declaration = STPDefaultCodeFormatterConstants.END_OF_LINE;
+ this.brace_position_for_switch = STPDefaultCodeFormatterConstants.END_OF_LINE;
+ this.brace_position_for_type_declaration = STPDefaultCodeFormatterConstants.END_OF_LINE;
+ this.comment_min_distance_between_code_and_line_comment = 1;
+ this.comment_preserve_white_space_between_code_and_line_comment = true;
+ this.never_indent_line_comments_on_first_column = true;
+// this.comment_clear_blank_lines = false;
+// this.comment_format = true;
+// this.comment_format_header = false;
+// this.comment_format_html = true;
+// this.comment_format_source = true;
+// this.comment_indent_parameter_description = true;
+// this.comment_indent_root_tags = true;
+// this.comment_insert_empty_line_before_root_tags = true;
+// this.comment_insert_new_line_for_parameter = true;
+// this.comment_line_length = 80;
+ this.continuation_indentation = 2;
+ this.continuation_indentation_for_initializer_list = 2;
+ this.indent_statements_compare_to_block = true;
+ this.indent_statements_compare_to_body = true;
+ this.indent_body_declarations_compare_to_namespace_header = false;
+// this.indent_body_declarations_compare_to_enum_declaration_header = true;
+ this.indent_body_declarations_compare_to_access_specifier = true;
+ this.indent_breaks_compare_to_cases = true;
+ this.indent_empty_lines = false;
+ this.indent_switchstatements_compare_to_cases = true;
+ this.indent_switchstatements_compare_to_switch = false;
+ this.indentation_size = 4;
+ this.insert_new_line_after_opening_brace_in_initializer_list = false;
+ this.insert_new_line_at_end_of_file_if_missing = false;
+ this.insert_new_line_before_catch_in_try_statement = false;
+ this.insert_new_line_before_closing_brace_in_initializer_list = false;
+ this.insert_new_line_before_else_in_if_statement = false;
+ this.insert_new_line_before_while_in_do_statement = false;
+ this.insert_new_line_before_identifier_in_function_declaration = false;
+ this.insert_new_line_in_empty_block = true;
+// this.insert_new_line_in_empty_method_body = true;
+// this.insert_new_line_in_empty_type_declaration = true;
+ this.insert_space_after_assignment_operator = true;
+ this.insert_space_after_binary_operator = true;
+ this.insert_space_after_closing_angle_bracket_in_template_arguments = true;
+ this.insert_space_after_closing_angle_bracket_in_template_parameters = true;
+ this.insert_space_after_closing_paren_in_cast = true;
+ this.insert_space_after_closing_brace_in_block = true;
+ this.insert_space_after_colon_in_base_clause = true;
+ this.insert_space_after_colon_in_case = true;
+ this.insert_space_after_colon_in_conditional = true;
+ this.insert_space_after_colon_in_labeled_statement = true;
+// this.insert_space_after_comma_in_allocation_expression = true;
+ this.insert_space_after_comma_in_initializer_list = true;
+ this.insert_space_after_comma_in_enum_declarations = true;
+ this.insert_space_after_comma_in_method_invocation_arguments = true;
+ this.insert_space_after_comma_in_method_declaration_parameters = true;
+ this.insert_space_after_comma_in_method_declaration_throws = true;
+ this.insert_space_after_comma_in_declarator_list = true;
+ this.insert_space_after_comma_in_expression_list = true;
+ this.insert_space_after_comma_in_base_types = true;
+ this.insert_space_after_comma_in_template_arguments = true;
+ this.insert_space_after_comma_in_template_parameters = true;
+// this.insert_space_after_ellipsis = true;
+// this.insert_space_after_opening_angle_bracket_in_parameterized_type_reference = false;
+ this.insert_space_after_opening_angle_bracket_in_template_arguments = false;
+ this.insert_space_after_opening_angle_bracket_in_template_parameters = false;
+ this.insert_space_after_opening_bracket = false;
+ this.insert_space_after_opening_brace_in_initializer_list = true;
+ this.insert_space_after_opening_paren_in_cast = false;
+ this.insert_space_after_opening_paren_in_catch = false;
+ this.insert_space_after_opening_paren_in_for = false;
+ this.insert_space_after_opening_paren_in_if = false;
+ this.insert_space_after_opening_paren_in_method_declaration = false;
+ this.insert_space_after_opening_paren_in_method_invocation = false;
+ this.insert_space_after_opening_paren_in_parenthesized_expression = false;
+ this.insert_space_after_opening_paren_in_switch = false;
+ this.insert_space_after_opening_paren_in_while = false;
+ this.insert_space_after_postfix_operator = false;
+ this.insert_space_after_prefix_operator = false;
+ this.insert_space_after_question_in_conditional = true;
+ this.insert_space_after_semicolon_in_for = true;
+ this.insert_space_after_unary_operator = false;
+ this.insert_space_before_assignment_operator = true;
+ this.insert_space_before_binary_operator = true;
+ this.insert_space_before_closing_angle_bracket_in_template_arguments = false;
+ this.insert_space_before_closing_angle_bracket_in_template_parameters = false;
+ this.insert_space_before_closing_brace_in_initializer_list = true;
+ this.insert_space_before_closing_bracket = false;
+ this.insert_space_before_closing_paren_in_cast = false;
+ this.insert_space_before_closing_paren_in_catch = false;
+ this.insert_space_before_closing_paren_in_for = false;
+ this.insert_space_before_closing_paren_in_if = false;
+ this.insert_space_before_closing_paren_in_method_declaration = false;
+ this.insert_space_before_closing_paren_in_method_invocation = false;
+ this.insert_space_before_closing_paren_in_parenthesized_expression = false;
+ this.insert_space_before_closing_paren_in_switch = false;
+ this.insert_space_before_closing_paren_in_while = false;
+ this.insert_space_before_colon_in_base_clause = false;
+ this.insert_space_before_colon_in_case = false;
+ this.insert_space_before_colon_in_conditional = true;
+ this.insert_space_before_colon_in_default = false;
+ this.insert_space_before_colon_in_labeled_statement = false;
+// this.insert_space_before_comma_in_allocation_expression = false;
+ this.insert_space_before_comma_in_initializer_list = false;
+ this.insert_space_before_comma_in_enum_declarations = false;
+// this.insert_space_before_comma_in_for_increments = false;
+// this.insert_space_before_comma_in_for_inits = false;
+ this.insert_space_before_comma_in_method_invocation_arguments = false;
+ this.insert_space_before_comma_in_method_declaration_parameters = false;
+ this.insert_space_before_comma_in_method_declaration_throws = false;
+ this.insert_space_before_comma_in_declarator_list = false;
+ this.insert_space_before_comma_in_expression_list = false;
+ this.insert_space_before_comma_in_base_types = false;
+ this.insert_space_before_comma_in_template_arguments = false;
+ this.insert_space_before_comma_in_template_parameters = false;
+// this.insert_space_before_ellipsis = false;
+// this.insert_space_before_parenthesized_expression_in_return = true;
+ this.insert_space_before_opening_angle_bracket_in_template_arguments = false;
+ this.insert_space_before_opening_angle_bracket_in_template_parameters = false;
+ this.insert_space_before_opening_brace_in_initializer_list = true;
+ this.insert_space_before_opening_brace_in_block = true;
+ this.insert_space_before_opening_brace_in_method_declaration = true;
+ this.insert_space_before_opening_brace_in_switch = true;
+ this.insert_space_before_opening_brace_in_type_declaration = true;
+ this.insert_space_before_opening_brace_in_namespace_declaration = true;
+ this.insert_space_before_opening_bracket = false;
+ this.insert_space_before_opening_paren_in_catch = true;
+ this.insert_space_before_opening_paren_in_exception_specification = true;
+ this.insert_space_before_opening_paren_in_for = true;
+ this.insert_space_before_opening_paren_in_if = true;
+ this.insert_space_before_opening_paren_in_method_invocation = false;
+ this.insert_space_before_opening_paren_in_method_declaration = false;
+ this.insert_space_before_opening_paren_in_switch = true;
+ this.insert_space_before_opening_paren_in_parenthesized_expression = false;
+ this.insert_space_before_opening_paren_in_while = true;
+ this.insert_space_before_postfix_operator = false;
+ this.insert_space_before_prefix_operator = false;
+ this.insert_space_before_question_in_conditional = true;
+ this.insert_space_before_semicolon = false;
+ this.insert_space_before_semicolon_in_for = false;
+ this.insert_space_before_unary_operator = false;
+ this.insert_space_between_empty_braces_in_initializer_list = false;
+ this.insert_space_between_empty_brackets = false;
+ this.insert_space_between_empty_parens_in_method_declaration = false;
+ this.insert_space_between_empty_parens_in_method_invocation = false;
+ this.insert_space_between_empty_parens_in_exception_specification = false;
+ this.compact_else_if = true;
+ this.keep_guardian_clause_on_one_line = false;
+ this.keep_else_statement_on_same_line = false;
+ this.keep_empty_initializer_list_on_one_line = false;
+ this.keep_simple_if_on_one_line = false;
+ this.keep_then_statement_on_same_line = false;
+ this.number_of_empty_lines_to_preserve = 1;
+ this.join_wrapped_lines = true;
+ this.put_empty_statement_on_new_line = true;
+ this.tab_size = 4;
+ this.page_width = 80;
+ this.tab_char = TAB;
+ this.use_tabs_only_for_leading_indentations = false;
+ }
+
+ /**
+ * Configure K&R style.
+ * <p>Example:</p>
+ * <pre>
+ * namespace foospace {
+ * int Foo() {
+ * if (isBar) {
+ * bar();
+ * return 1;
+ * } else
+ * return 0;
+ * }
+ * }
+ * </pre>
+ * @see "http://en.wikipedia.org/wiki/Indent_style"
+ */
+ public void setKandRSettings() {
+ setDefaultSettings();
+ }
+
+ /**
+ * Configure BSD/Allman style.
+ * <p>Example:</p>
+ * <pre>
+ * namespace foospace
+ * {
+ * int Foo()
+ * {
+ * if (isBar)
+ * {
+ * bar();
+ * return 1;
+ * }
+ * else
+ * return 0;
+ * }
+ * }
+ * </pre>
+ * @see "http://en.wikipedia.org/wiki/Indent_style"
+ */
+ public void setAllmanSettings() {
+ setDefaultSettings();
+ this.brace_position_for_initializer_list = STPDefaultCodeFormatterConstants.NEXT_LINE;
+ this.brace_position_for_block = STPDefaultCodeFormatterConstants.NEXT_LINE;
+ this.brace_position_for_block_in_case = STPDefaultCodeFormatterConstants.NEXT_LINE;
+// this.brace_position_for_enum_declaration = STPDefaultCodeFormatterConstants.NEXT_LINE;
+ this.brace_position_for_method_declaration = STPDefaultCodeFormatterConstants.NEXT_LINE;
+ this.brace_position_for_type_declaration = STPDefaultCodeFormatterConstants.NEXT_LINE;
+ this.brace_position_for_namespace_declaration = STPDefaultCodeFormatterConstants.NEXT_LINE;
+ this.brace_position_for_switch = STPDefaultCodeFormatterConstants.NEXT_LINE;
+
+ this.indent_statements_compare_to_block = true;
+ this.indent_statements_compare_to_body = true;
+ this.indent_body_declarations_compare_to_namespace_header = false;
+// this.indent_body_declarations_compare_to_enum_declaration_header = true;
+ this.indent_breaks_compare_to_cases = true;
+ this.indent_empty_lines = false;
+ this.indent_switchstatements_compare_to_cases = true;
+ this.indent_switchstatements_compare_to_switch = false;
+ this.indentation_size = 4;
+
+ this.insert_new_line_after_opening_brace_in_initializer_list = false;
+ this.insert_new_line_at_end_of_file_if_missing = false;
+ this.insert_new_line_before_closing_brace_in_initializer_list = false;
+ this.insert_new_line_before_else_in_if_statement = true;
+ this.insert_new_line_in_empty_block = true;
+// this.insert_new_line_in_empty_enum_declaration = true;
+// this.insert_new_line_in_empty_method_body = true;
+// this.insert_new_line_in_empty_type_declaration = true;
+
+ this.compact_else_if = true;
+ this.keep_guardian_clause_on_one_line = false;
+ this.keep_else_statement_on_same_line = false;
+ this.keep_empty_initializer_list_on_one_line = false;
+ this.keep_simple_if_on_one_line = false;
+ this.keep_then_statement_on_same_line = false;
+ this.put_empty_statement_on_new_line = true;
+ this.tab_size = 4;
+ this.page_width = 80;
+ this.tab_char = TAB;
+ this.use_tabs_only_for_leading_indentations = false;
+ }
+
+
+
+ /**
+ * Configure GNU style.
+ * <p>Example:</p>
+ * <pre>
+ * namespace foospace
+ * {
+ * int Foo()
+ * {
+ * if (isBar)
+ * {
+ * bar();
+ * return 1;
+ * }
+ * else
+ * return 0;
+ * }
+ * }
+ * </pre>
+ * @see "http://en.wikipedia.org/wiki/Indent_style"
+ */
+ public void setGNUSettings() {
+ setDefaultSettings();
+ this.brace_position_for_initializer_list = STPDefaultCodeFormatterConstants.NEXT_LINE_SHIFTED;
+ this.brace_position_for_block = STPDefaultCodeFormatterConstants.NEXT_LINE_SHIFTED;
+ this.brace_position_for_block_in_case = STPDefaultCodeFormatterConstants.NEXT_LINE_SHIFTED;
+// this.brace_position_for_enum_declaration = STPDefaultCodeFormatterConstants.NEXT_LINE_SHIFTED;
+ this.brace_position_for_method_declaration = STPDefaultCodeFormatterConstants.NEXT_LINE;
+ this.brace_position_for_type_declaration = STPDefaultCodeFormatterConstants.NEXT_LINE;
+ this.brace_position_for_namespace_declaration = STPDefaultCodeFormatterConstants.NEXT_LINE;
+ this.brace_position_for_switch = STPDefaultCodeFormatterConstants.NEXT_LINE_SHIFTED;
+
+ this.indent_statements_compare_to_block = true;
+ this.indent_statements_compare_to_body = true;
+ this.indent_body_declarations_compare_to_namespace_header = true;
+// this.indent_body_declarations_compare_to_enum_declaration_header = true;
+ this.indent_declaration_compare_to_template_header = true;
+ this.indent_breaks_compare_to_cases = true;
+ this.indent_empty_lines = false;
+ this.indent_switchstatements_compare_to_cases = true;
+ this.indent_switchstatements_compare_to_switch = false;
+ this.indentation_size = 8;
+
+ this.insert_new_line_after_opening_brace_in_initializer_list = false;
+ this.insert_new_line_after_template_declaration = true;
+ this.insert_new_line_at_end_of_file_if_missing = false;
+ this.insert_new_line_before_catch_in_try_statement = true;
+ this.insert_new_line_before_closing_brace_in_initializer_list = false;
+ this.insert_new_line_before_else_in_if_statement = true;
+ this.insert_new_line_before_identifier_in_function_declaration = true;
+ this.insert_new_line_before_while_in_do_statement = true;
+ this.insert_new_line_in_empty_block = true;
+// this.insert_new_line_in_empty_enum_declaration = false;
+// this.insert_new_line_in_empty_method_body = false;
+// this.insert_new_line_in_empty_type_declaration = false;
+
+ this.insert_space_before_colon_in_base_clause = true;
+
+ this.compact_else_if = true;
+ this.keep_guardian_clause_on_one_line = false;
+ this.keep_else_statement_on_same_line = false;
+ this.keep_empty_initializer_list_on_one_line = false;
+ this.keep_simple_if_on_one_line = false;
+ this.keep_then_statement_on_same_line = false;
+ this.put_empty_statement_on_new_line = true;
+ this.tab_size = 2;
+ this.page_width = 80;
+ this.tab_char = SPACE;
+ this.use_tabs_only_for_leading_indentations = false;
+ }
+
+ /**
+ * Configure Whitesmiths style.
+ * <p>Example:</p>
+ * <pre>
+ * namespace foospace
+ * {
+ * int Foo()
+ * {
+ * if (isBar)
+ * {
+ * bar();
+ * return 1;
+ * }
+ * else
+ * return 0;
+ * }
+ * }
+ * </pre>
+ * @see "http://en.wikipedia.org/wiki/Indent_style"
+ */
+ public void setWhitesmitsSettings() {
+ setDefaultSettings();
+ this.alignment_for_expressions_in_initializer_list = STPAlignment.M_ONE_PER_LINE_SPLIT;
+ this.alignment_for_enumerator_list = STPAlignment.M_ONE_PER_LINE_SPLIT | STPAlignment.M_FORCE;
+
+ this.brace_position_for_initializer_list = STPDefaultCodeFormatterConstants.NEXT_LINE_SHIFTED;
+ this.brace_position_for_block = STPDefaultCodeFormatterConstants.NEXT_LINE_SHIFTED;
+ this.brace_position_for_block_in_case = STPDefaultCodeFormatterConstants.NEXT_LINE_SHIFTED;
+ this.brace_position_for_method_declaration = STPDefaultCodeFormatterConstants.NEXT_LINE_SHIFTED;
+ this.brace_position_for_type_declaration = STPDefaultCodeFormatterConstants.NEXT_LINE_SHIFTED;
+ this.brace_position_for_namespace_declaration = STPDefaultCodeFormatterConstants.NEXT_LINE_SHIFTED;
+ this.brace_position_for_switch = STPDefaultCodeFormatterConstants.NEXT_LINE_SHIFTED;
+
+ this.indent_statements_compare_to_block = false;
+ this.indent_statements_compare_to_body = false;
+ this.indent_body_declarations_compare_to_namespace_header = false;
+ this.indent_breaks_compare_to_cases = true;
+ this.indent_empty_lines = false;
+ this.indent_switchstatements_compare_to_cases = true;
+ this.indent_switchstatements_compare_to_switch = false;
+ this.indentation_size = 4;
+
+ this.insert_new_line_after_opening_brace_in_initializer_list = true;
+ this.insert_new_line_at_end_of_file_if_missing = false;
+ this.insert_new_line_before_catch_in_try_statement = true;
+ this.insert_new_line_before_closing_brace_in_initializer_list = true;
+ this.insert_new_line_before_else_in_if_statement = true;
+ this.insert_new_line_before_while_in_do_statement = true;
+ this.insert_new_line_in_empty_block = true;
+// this.insert_new_line_in_empty_enum_declaration = true;
+// this.insert_new_line_in_empty_method_body = true;
+// this.insert_new_line_in_empty_type_declaration = true;
+
+ this.compact_else_if = true;
+ this.keep_guardian_clause_on_one_line = false;
+ this.keep_else_statement_on_same_line = false;
+ this.keep_empty_initializer_list_on_one_line = false;
+ this.keep_simple_if_on_one_line = false;
+ this.keep_then_statement_on_same_line = false;
+ this.put_empty_statement_on_new_line = true;
+ this.tab_size = 8;
+ this.page_width = 80;
+ this.tab_char = MIXED;
+ this.use_tabs_only_for_leading_indentations = false;
+ }
+}
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPDocumentProvider.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPDocumentProvider.java
index 2b5a8ea978..868f7829f3 100644
--- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPDocumentProvider.java
+++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPDocumentProvider.java
@@ -13,6 +13,7 @@
package org.eclipse.linuxtools.internal.systemtap.ui.ide.editors.stp;
import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IDocumentExtension3;
import org.eclipse.jface.text.IDocumentPartitioner;
import org.eclipse.jface.text.rules.FastPartitioner;
import org.eclipse.jface.text.source.AnnotationModel;
@@ -25,11 +26,13 @@ public class STPDocumentProvider extends SimpleDocumentProvider {
protected void setupDocument(IDocument document) {
if (document != null) {
IDocumentPartitioner partitioner = new FastPartitioner(
- new STPPartitionScanner(), new String[] {
- STPPartitionScanner.STP_COMMENT,
- STPPartitionScanner.STP_PROBE });
+ new STPPartitionScanner(), STPPartitionScanner.STP_PARTITION_TYPES);
partitioner.connect(document);
- document.setDocumentPartitioner(partitioner);
+ IDocumentPartitioner partitioner2 = new FastPartitioner(
+ new STPProbeScanner(), STPProbeScanner.STP_PROBE_PARTITION_TYPES);
+ partitioner2.connect(document);
+ ((IDocumentExtension3)document).setDocumentPartitioner(STPPartitionScanner.STP_PARTITIONING, partitioner);
+ ((IDocumentExtension3)document).setDocumentPartitioner(STPProbeScanner.STP_PROBE_PARTITIONING, partitioner2);
}
}
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPHeuristicScanner.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPHeuristicScanner.java
new file mode 100644
index 0000000000..7361125df6
--- /dev/null
+++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPHeuristicScanner.java
@@ -0,0 +1,1241 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2012, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ * Sergey Prigogin, Google
+ * Anton Leherbauer (Wind River Systems)
+ * Nathan Ridge
+ * Red Hat Inc. - modified for use in SystemTap
+ *******************************************************************************/
+package org.eclipse.linuxtools.internal.systemtap.ui.ide.editors.stp;
+
+import java.util.Arrays;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITypedRegion;
+import org.eclipse.jface.text.Region;
+import org.eclipse.jface.text.TextUtilities;
+import org.eclipse.jface.text.TypedRegion;
+
+/**
+ * Utility methods for heuristic based C manipulations in an incomplete C source file.
+ *
+ * <p>An instance holds some internal position in the document and is therefore not thread-safe.</p>
+ */
+public final class STPHeuristicScanner implements STPSymbols {
+ /**
+ * Returned by all methods when the requested position could not be found, or if a
+ * {@link BadLocationException} was thrown while scanning.
+ */
+ public static final int NOT_FOUND= -1;
+
+ /**
+ * Special bound parameter that means either -1 (backward scanning) or
+ * <code>fDocument.getLength()</code> (forward scanning).
+ */
+ public static final int UNBOUND= -2;
+
+
+ /* character constants */
+ private static final char LBRACE= '{';
+ private static final char RBRACE= '}';
+ private static final char LPAREN= '(';
+ private static final char RPAREN= ')';
+ private static final char SEMICOLON= ';';
+ private static final char COLON= ':';
+ private static final char COMMA= ',';
+ private static final char LBRACKET= '[';
+ private static final char RBRACKET= ']';
+ private static final char QUESTIONMARK= '?';
+ private static final char EQUAL= '=';
+ private static final char LANGLE= '<';
+ private static final char RANGLE= '>';
+ private static final char DOT= '.';
+ private static final char MINUS= '-';
+ private static final char PLUS= '+';
+ private static final char TILDE= '~';
+
+ /**
+ * Specifies the stop condition, upon which the <code>scanXXX</code> methods will decide whether
+ * to keep scanning or not. This interface may implemented by clients.
+ */
+ private static abstract class StopCondition {
+ /**
+ * Instructs the scanner to return the current position.
+ *
+ * @param ch the char at the current position
+ * @param position the current position
+ * @param forward the iteration direction
+ * @return <code>true</code> if the stop condition is met.
+ */
+ public abstract boolean stop(char ch, int position, boolean forward);
+
+ /**
+ * Asks the condition to return the next position to query. The default
+ * is to return the next/previous position.
+ *
+ * @return the next position to scan
+ */
+ public int nextPosition(int position, boolean forward) {
+ return forward ? position + 1 : position - 1;
+ }
+ }
+
+ /**
+ * Stops upon a non-whitespace (as defined by {@link Character#isWhitespace(char)}) character.
+ */
+ private static class NonWhitespace extends StopCondition {
+ /*
+ * @see org.eclipse.cdt.internal.ui.text.CHeuristicScanner.StopCondition#stop(char)
+ */
+ @Override
+ public boolean stop(char ch, int position, boolean forward) {
+ return !Character.isWhitespace(ch);
+ }
+ }
+
+ /**
+ * Stops upon a non-whitespace character in the default partition.
+ *
+ * @see NonWhitespace
+ */
+ private final class NonWhitespaceDefaultPartition extends NonWhitespace {
+ /*
+ * @see org.eclipse.cdt.internal.ui.text.CHeuristicScanner.StopCondition#stop(char)
+ */
+ @Override
+ public boolean stop(char ch, int position, boolean forward) {
+ return super.stop(ch, position, true) && isDefaultPartition(position);
+ }
+
+ /*
+ * @see org.eclipse.cdt.internal.ui.text.CHeuristicScanner.StopCondition#nextPosition(int, boolean)
+ */
+ @Override
+ public int nextPosition(int position, boolean forward) {
+ ITypedRegion partition= getPartition(position);
+ if (fPartition.equals(partition.getType()))
+ return super.nextPosition(position, forward);
+
+ if (forward) {
+ int end= partition.getOffset() + partition.getLength();
+ if (position < end)
+ return end;
+ } else {
+ int offset= partition.getOffset();
+ if (position > offset)
+ return offset - 1;
+ }
+ return super.nextPosition(position, forward);
+ }
+ }
+
+ /**
+ * Stops upon a non-java identifier (as defined by {@link Character#isJavaIdentifierPart(char)}) character.
+ */
+ private static class NonJavaIdentifierPart extends StopCondition {
+ /*
+ * @see org.eclipse.cdt.internal.ui.text.CHeuristicScanner.StopCondition#stop(char)
+ */
+ @Override
+ public boolean stop(char ch, int position, boolean forward) {
+ return !Character.isJavaIdentifierPart(ch);
+ }
+ }
+
+ /**
+ * Stops upon a non-java identifier character in the default partition.
+ *
+ * @see NonJavaIdentifierPart
+ */
+ private final class NonJavaIdentifierPartDefaultPartition extends NonJavaIdentifierPart {
+ /*
+ * @see org.eclipse.cdt.internal.ui.text.CHeuristicScanner.StopCondition#stop(char)
+ */
+ @Override
+ public boolean stop(char ch, int position, boolean forward) {
+ return super.stop(ch, position, true) || !isDefaultPartition(position);
+ }
+
+ /*
+ * @see org.eclipse.cdt.internal.ui.text.CHeuristicScanner.StopCondition#nextPosition(int, boolean)
+ */
+ @Override
+ public int nextPosition(int position, boolean forward) {
+ ITypedRegion partition= getPartition(position);
+ if (fPartition.equals(partition.getType()))
+ return super.nextPosition(position, forward);
+
+ if (forward) {
+ int end= partition.getOffset() + partition.getLength();
+ if (position < end)
+ return end;
+ } else {
+ int offset= partition.getOffset();
+ if (position > offset)
+ return offset - 1;
+ }
+ return super.nextPosition(position, forward);
+ }
+ }
+
+ /**
+ * Stops upon a character in the default partition that matches the given character list.
+ */
+ private final class CharacterMatch extends StopCondition {
+ private final char[] fChars;
+
+ /**
+ * Creates a new instance.
+ * @param ch the single character to match
+ */
+ public CharacterMatch(char ch) {
+ this(new char[] {ch});
+ }
+
+ /**
+ * Creates a new instance.
+ * @param chars the chars to match.
+ */
+ public CharacterMatch(char[] chars) {
+ Assert.isNotNull(chars);
+ Assert.isTrue(chars.length > 0);
+ fChars= chars;
+ Arrays.sort(chars);
+ }
+
+ /*
+ * @see org.eclipse.cdt.internal.ui.text.CHeuristicScanner.StopCondition#stop(char, int)
+ */
+ @Override
+ public boolean stop(char ch, int position, boolean forward) {
+ return Arrays.binarySearch(fChars, ch) >= 0 && isDefaultPartition(position);
+ }
+
+ /*
+ * @see org.eclipse.cdt.internal.ui.text.CHeuristicScanner.StopCondition#nextPosition(int, boolean)
+ */
+ @Override
+ public int nextPosition(int position, boolean forward) {
+ ITypedRegion partition= getPartition(position);
+ if (fPartition.equals(partition.getType()))
+ return super.nextPosition(position, forward);
+
+ if (forward) {
+ int end= partition.getOffset() + partition.getLength();
+ if (position < end)
+ return end;
+ } else {
+ int offset= partition.getOffset();
+ if (position > offset)
+ return offset - 1;
+ }
+ return super.nextPosition(position, forward);
+ }
+ }
+
+ /** The document being scanned. */
+ private final IDocument fDocument;
+ /** The partitioning being used for scanning. */
+ private final String fPartitioning;
+ /** The partition to scan in. */
+ private final String fPartition;
+
+ /* internal scan state */
+
+ /** the most recently read character. */
+ private char fChar;
+ /** the most recently read position. */
+ private int fPos;
+ /**
+ * The most recently used partition.
+ */
+ private ITypedRegion fCachedPartition= new TypedRegion(-1, 0, "__no_partition_at_all"); //$NON-NLS-1$
+
+ /* preset stop conditions */
+ private final StopCondition fNonWSDefaultPart= new NonWhitespaceDefaultPartition();
+ private static final StopCondition fNonWS= new NonWhitespace();
+ private final StopCondition fNonIdent= new NonJavaIdentifierPartDefaultPartition();
+
+ /**
+ * Creates a new instance.
+ *
+ * @param document the document to scan
+ * @param partitioning the partitioning to use for scanning
+ * @param partition the partition to scan in
+ */
+ public STPHeuristicScanner(IDocument document, String partitioning, String partition) {
+ Assert.isLegal(document != null);
+ Assert.isLegal(partitioning != null);
+ Assert.isLegal(partition != null);
+ fDocument= document;
+ fPartitioning= partitioning;
+ fPartition= partition;
+ }
+
+ /**
+ * Calls <code>this(document, STPPartitionScanner.STP_PARTITIONING, IDocument.DEFAULT_CONTENT_TYPE)</code>.
+ *
+ * @param document the document to scan.
+ */
+ public STPHeuristicScanner(IDocument document) {
+ this(document, STPPartitionScanner.STP_PARTITIONING, IDocument.DEFAULT_CONTENT_TYPE);
+ }
+
+ /**
+ * Returns the most recent internal scan position.
+ *
+ * @return the most recent internal scan position.
+ */
+ public int getPosition() {
+ return fPos;
+ }
+
+ /**
+ * Returns the next token in forward direction, starting at <code>start</code>, and not extending
+ * further than <code>bound</code>. The return value is one of the constants defined in {@link STPSymbols}.
+ * After a call, {@link #getPosition()} will return the position just after the scanned token
+ * (i.e. the next position that will be scanned).
+ *
+ * @param start the first character position in the document to consider
+ * @param bound the first position not to consider any more
+ * @return a constant from {@link STPSymbols} describing the next token
+ */
+ public int nextToken(int start, int bound) {
+ int pos= scanForward(start, bound, fNonWS);
+ if (pos == NOT_FOUND)
+ return TokenEOF;
+ try {
+ // check for string or char literal
+ char ch = fDocument.getChar(pos);
+ if (ch == '"' || ch == '\'') {
+ fChar= ch;
+ fPos= fNonWSDefaultPart.nextPosition(pos, true);
+ return TokenOTHER;
+ }
+ } catch (BadLocationException exc) {
+ }
+ pos= scanForward(pos, bound, fNonWSDefaultPart);
+ if (pos == NOT_FOUND)
+ return TokenEOF;
+
+ fPos++;
+
+ switch (fChar) {
+ case LBRACE:
+ return TokenLBRACE;
+ case RBRACE:
+ return TokenRBRACE;
+ case LBRACKET:
+ return TokenLBRACKET;
+ case RBRACKET:
+ return TokenRBRACKET;
+ case LPAREN:
+ return TokenLPAREN;
+ case RPAREN:
+ return TokenRPAREN;
+ case SEMICOLON:
+ return TokenSEMICOLON;
+ case COLON:
+ switch (peekNextChar()) {
+ case COLON:
+ ++fPos;
+ return TokenDOUBLECOLON;
+ }
+ return TokenCOLON;
+ case COMMA:
+ return TokenCOMMA;
+ case QUESTIONMARK:
+ return TokenQUESTIONMARK;
+ case EQUAL:
+ return TokenEQUAL;
+ case LANGLE:
+ switch (peekNextChar()) {
+ case LANGLE:
+ ++fPos;
+ if (peekNextChar() == LANGLE) {
+ ++fPos;
+ return TokenAggregate;
+ }
+ return TokenSHIFTLEFT;
+ case EQUAL:
+ ++fPos;
+ return TokenOTHER;
+ }
+ return TokenLESSTHAN;
+ case RANGLE:
+ switch (peekNextChar()) {
+ case RANGLE:
+ ++fPos;
+ return TokenSHIFTRIGHT;
+ case EQUAL:
+ ++fPos;
+ return TokenOTHER;
+ }
+ return TokenGREATERTHAN;
+ case DOT:
+ return TokenDOT;
+ case MINUS:
+ switch (peekNextChar()) {
+ case RANGLE:
+ ++fPos;
+ return TokenARROW;
+ }
+ return TokenMINUS;
+ case PLUS:
+ return TokenPLUS;
+ case TILDE:
+ return TokenTILDE;
+ }
+
+ // else
+ if (Character.isJavaIdentifierPart(fChar)) {
+ // assume an identifier or keyword
+ int from= pos, to;
+ pos= scanForward(pos + 1, bound, fNonIdent);
+ if (pos == NOT_FOUND)
+ to= bound == UNBOUND ? fDocument.getLength() : bound;
+ else
+ to= pos;
+
+ String identOrKeyword;
+ try {
+ identOrKeyword= fDocument.get(from, to - from);
+ } catch (BadLocationException e) {
+ return TokenEOF;
+ }
+
+ return getToken(identOrKeyword);
+
+
+ }
+ // operators, number literals etc
+ return TokenOTHER;
+ }
+
+ /**
+ * Returns the next token in backward direction, starting at <code>start</code>, and not extending
+ * further than <code>bound</code>. The return value is one of the constants defined in {@link STPSymbols}.
+ * After a call, {@link #getPosition()} will return the position just before the scanned token
+ * starts (i.e. the next position that will be scanned).
+ *
+ * @param start the first character position in the document to consider
+ * @param bound the first position not to consider any more
+ * @return a constant from {@link STPSymbols} describing the previous token
+ */
+ public int previousToken(int start, int bound) {
+ int pos= scanBackward(start, bound, fNonWSDefaultPart);
+ if (pos == NOT_FOUND)
+ return TokenEOF;
+
+ fPos--;
+
+ switch (fChar) {
+ case LBRACE:
+ return TokenLBRACE;
+ case RBRACE:
+ return TokenRBRACE;
+ case LBRACKET:
+ return TokenLBRACKET;
+ case RBRACKET:
+ return TokenRBRACKET;
+ case LPAREN:
+ return TokenLPAREN;
+ case RPAREN:
+ return TokenRPAREN;
+ case SEMICOLON:
+ return TokenSEMICOLON;
+ case COLON:
+ switch (peekPreviousChar()) {
+ case COLON:
+ --fPos;
+ return TokenDOUBLECOLON;
+ }
+ return TokenCOLON;
+ case COMMA:
+ return TokenCOMMA;
+ case QUESTIONMARK:
+ return TokenQUESTIONMARK;
+ case EQUAL:
+ switch (peekPreviousChar()) {
+ case RANGLE:
+ case LANGLE:
+ --fPos;
+ return TokenOTHER;
+ }
+ return TokenEQUAL;
+ case LANGLE:
+ switch (peekPreviousChar()) {
+ case LANGLE:
+ --fPos;
+ return TokenSHIFTLEFT;
+ }
+ return TokenLESSTHAN;
+ case RANGLE:
+ switch (peekPreviousChar()) {
+ case RANGLE:
+ --fPos;
+ return TokenSHIFTRIGHT;
+ case MINUS:
+ --fPos;
+ return TokenARROW;
+ }
+ return TokenGREATERTHAN;
+ case DOT:
+ return TokenDOT;
+ case MINUS:
+ return TokenMINUS;
+ case PLUS:
+ return TokenPLUS;
+ case TILDE:
+ return TokenTILDE;
+ }
+
+ // else
+ if (Character.isJavaIdentifierPart(fChar)) {
+ // assume an ident or keyword
+ int from, to= pos + 1;
+ pos= scanBackward(pos - 1, bound, fNonIdent);
+ if (pos == NOT_FOUND)
+ from= bound == UNBOUND ? 0 : bound + 1;
+ else
+ from= pos + 1;
+
+ String identOrKeyword;
+ try {
+ identOrKeyword= fDocument.get(from, to - from);
+ } catch (BadLocationException e) {
+ return TokenEOF;
+ }
+
+ return getToken(identOrKeyword);
+ }
+ // operators, number literals etc
+ return TokenOTHER;
+ }
+
+ /**
+ * @return the next char without shifting the position
+ */
+ private char peekNextChar() {
+ if (fPos + 1 < fDocument.getLength()) {
+ try {
+ return fDocument.getChar(fPos + 1);
+ } catch (BadLocationException exc) {
+ }
+ }
+ return (char)-1;
+ }
+
+ /**
+ * @return the previous char without shifting the position
+ */
+ private char peekPreviousChar() {
+ if (fPos >= 0) {
+ try {
+ return fDocument.getChar(fPos);
+ } catch (BadLocationException e) {
+ }
+ }
+ return (char)-1;
+ }
+
+ /**
+ * Returns one of the keyword constants or <code>TokenIDENT</code> for a scanned identifier.
+ *
+ * @param s a scanned identifier
+ * @return one of the constants defined in {@link STPSymbols}
+ */
+ private int getToken(String s) {
+ Assert.isNotNull(s);
+
+ switch (s.length()) {
+ case 2:
+ if ("if".equals(s)) //$NON-NLS-1$
+ return TokenIF;
+ if ("do".equals(s)) //$NON-NLS-1$
+ return TokenDO;
+ break;
+ case 3:
+ if ("for".equals(s)) //$NON-NLS-1$
+ return TokenFOR;
+ if ("try".equals(s)) //$NON-NLS-1$
+ return TokenTRY;
+ if ("new".equals(s)) //$NON-NLS-1$
+ return TokenNEW;
+ break;
+ case 4:
+ if ("case".equals(s)) //$NON-NLS-1$
+ return TokenCASE;
+ if ("else".equals(s)) //$NON-NLS-1$
+ return TokenELSE;
+ if ("enum".equals(s)) //$NON-NLS-1$
+ return TokenENUM;
+ if ("goto".equals(s)) //$NON-NLS-1$
+ return TokenGOTO;
+ break;
+ case 5:
+ if ("break".equals(s)) //$NON-NLS-1$
+ return TokenBREAK;
+ if ("catch".equals(s)) //$NON-NLS-1$
+ return TokenCATCH;
+ if ("class".equals(s)) //$NON-NLS-1$
+ return TokenCLASS;
+ if ("const".equals(s)) //$NON-NLS-1$
+ return TokenCONST;
+ if ("while".equals(s)) //$NON-NLS-1$
+ return TokenWHILE;
+ if ("union".equals(s)) //$NON-NLS-1$
+ return TokenUNION;
+ if ("using".equals(s)) //$NON-NLS-1$
+ return TokenUSING;
+ if ("throw".equals(s)) //$NON-NLS-1$
+ return TokenTHROW;
+ break;
+ case 6:
+ if ("delete".equals(s)) //$NON-NLS-1$
+ return TokenDELETE;
+ if ("public".equals(s)) //$NON-NLS-1$
+ return TokenPUBLIC;
+ if ("return".equals(s)) //$NON-NLS-1$
+ return TokenRETURN;
+ if ("static".equals(s)) //$NON-NLS-1$
+ return TokenSTATIC;
+ if ("struct".equals(s)) //$NON-NLS-1$
+ return TokenSTRUCT;
+ if ("switch".equals(s)) //$NON-NLS-1$
+ return TokenSWITCH;
+ if ("extern".equals(s)) //$NON-NLS-1$
+ return TokenEXTERN;
+ break;
+ case 7:
+ if ("default".equals(s)) //$NON-NLS-1$
+ return TokenDEFAULT;
+ if ("foreach".equals(s)) //$NON-NLS-1$
+ return TokenFOREACH;
+ if ("private".equals(s)) //$NON-NLS-1$
+ return TokenPRIVATE;
+ if ("typedef".equals(s)) //$NON-NLS-1$
+ return TokenTYPEDEF;
+ if ("virtual".equals(s)) //$NON-NLS-1$
+ return TokenVIRTUAL;
+ break;
+ case 8:
+ if ("operator".equals(s)) //$NON-NLS-1$
+ return TokenOPERATOR;
+ if ("template".equals(s)) //$NON-NLS-1$
+ return TokenTEMPLATE;
+ if ("typename".equals(s)) //$NON-NLS-1$
+ return TokenTYPENAME;
+ break;
+ case 9:
+ if ("namespace".equals(s)) //$NON-NLS-1$
+ return TokenNAMESPACE;
+ if ("protected".equals(s)) //$NON-NLS-1$
+ return TokenPROTECTED;
+ }
+ return TokenIDENT;
+ }
+
+ /**
+ * Returns the position of the closing peer character (forward search). Any scopes introduced
+ * by opening peers are skipped. All peers accounted for must reside in the default partition.
+ *
+ * <p>Note that <code>start</code> must not point to the opening peer, but to the first
+ * character being searched.</p>
+ *
+ * @param start the start position
+ * @param openingPeer the opening peer character (e.g. '{')
+ * @param closingPeer the closing peer character (e.g. '}')
+ * @return the matching peer character position, or <code>NOT_FOUND</code>
+ */
+ public int findClosingPeer(int start, final char openingPeer, final char closingPeer) {
+ return findClosingPeer(start, UNBOUND, openingPeer, closingPeer);
+ }
+
+ /**
+ * Returns the position of the closing peer character (forward search). Any scopes introduced by opening peers
+ * are skipped. All peers accounted for must reside in the default partition.
+ *
+ * <p>Note that <code>start</code> must not point to the opening peer, but to the first
+ * character being searched.</p>
+ *
+ * @param start the start position
+ * @param bound the bound
+ * @param openingPeer the opening peer character (e.g. '{')
+ * @param closingPeer the closing peer character (e.g. '}')
+ * @return the matching peer character position, or <code>NOT_FOUND</code>
+ */
+ public int findClosingPeer(int start, int bound, final char openingPeer, final char closingPeer) {
+ Assert.isLegal(start >= 0);
+
+ try {
+ int depth= 1;
+ start -= 1;
+ while (true) {
+ start= scanForward(start + 1, bound, new CharacterMatch(new char[] {openingPeer, closingPeer}));
+ if (start == NOT_FOUND)
+ return NOT_FOUND;
+
+ if (fDocument.getChar(start) == openingPeer)
+ depth++;
+ else
+ depth--;
+
+ if (depth == 0)
+ return start;
+ }
+
+ } catch (BadLocationException e) {
+ return NOT_FOUND;
+ }
+ }
+
+ /**
+ * Returns the position of the opening peer character (backward search). Any scopes introduced by closing peers
+ * are skipped. All peers accounted for must reside in the default partition.
+ *
+ * <p>Note that <code>start</code> must not point to the closing peer, but to the first
+ * character being searched.</p>
+ *
+ * @param start the start position
+ * @param openingPeer the opening peer character (e.g. '{')
+ * @param closingPeer the closing peer character (e.g. '}')
+ * @return the matching peer character position, or <code>NOT_FOUND</code>
+ */
+ public int findOpeningPeer(int start, char openingPeer, char closingPeer) {
+ return findOpeningPeer(start, STPHeuristicScanner.UNBOUND, openingPeer, closingPeer);
+ }
+
+ /**
+ * Returns the position of the opening peer character (backward search). Any scopes introduced by closing peers
+ * are skipped. All peers accounted for must reside in the default partition.
+ *
+ * <p>Note that <code>start</code> must not point to the closing peer, but to the first
+ * character being searched.</p>
+ *
+ * @param start the start position
+ * @param bound the bound
+ * @param openingPeer the opening peer character (e.g. '{')
+ * @param closingPeer the closing peer character (e.g. '}')
+ * @return the matching peer character position, or <code>NOT_FOUND</code>
+ */
+ public int findOpeningPeer(int start, int bound, char openingPeer, char closingPeer) {
+ Assert.isLegal(start < fDocument.getLength());
+
+ try {
+ final CharacterMatch match= new CharacterMatch(new char[] {openingPeer, closingPeer});
+ int depth= 1;
+ start += 1;
+ while (true) {
+ start= scanBackward(start - 1, bound, match);
+ if (start == NOT_FOUND)
+ return NOT_FOUND;
+
+ if (fDocument.getChar(start) == closingPeer)
+ depth++;
+ else
+ depth--;
+
+ if (depth == 0)
+ return start;
+ }
+
+ } catch (BadLocationException e) {
+ return NOT_FOUND;
+ }
+ }
+
+ /**
+ * Computes the surrounding block around <code>offset</code>. The search is started at the
+ * beginning of <code>offset</code>, i.e. an opening brace at <code>offset</code> will not be
+ * part of the surrounding block, but a closing brace will.
+ *
+ * @param offset the offset for which the surrounding block is computed
+ * @return a region describing the surrounding block, or <code>null</code> if none can be found
+ */
+ public IRegion findSurroundingBlock(int offset) {
+ if (offset < 1 || offset >= fDocument.getLength())
+ return null;
+
+ int begin= findOpeningPeer(offset - 1, STPHeuristicScanner.UNBOUND, LBRACE, RBRACE);
+ int end= findClosingPeer(offset, UNBOUND, LBRACE, RBRACE);
+ if (begin == NOT_FOUND || end == NOT_FOUND)
+ return null;
+ return new Region(begin, end + 1 - begin);
+ }
+
+ /**
+ * Finds the smallest position in <code>fDocument</code> such that the position is &gt;= <code>position</code>
+ * and &lt; <code>bound</code> and <code>Character.isWhitespace(fDocument.getChar(pos))</code> evaluates to <code>false</code>
+ * and the position is in the default partition.
+ *
+ * @param position the first character position in <code>fDocument</code> to be considered
+ * @param bound the first position in <code>fDocument</code> to not consider any more, with <code>bound</code> &gt; <code>position</code>, or <code>UNBOUND</code>
+ * @return the smallest position of a non-whitespace character in [<code>position</code>, <code>bound</code>) that resides in a C partition, or <code>NOT_FOUND</code> if none can be found
+ */
+ public int findNonWhitespaceForward(int position, int bound) {
+ return scanForward(position, bound, fNonWSDefaultPart);
+ }
+
+ /**
+ * Finds the smallest position in <code>fDocument</code> such that the position is &gt;= <code>position</code>
+ * and &lt; <code>bound</code> and <code>Character.isWhitespace(fDocument.getChar(pos))</code> evaluates to <code>false</code>.
+ *
+ * @param position the first character position in <code>fDocument</code> to be considered
+ * @param bound the first position in <code>fDocument</code> to not consider any more, with <code>bound</code> &gt; <code>position</code>, or <code>UNBOUND</code>
+ * @return the smallest position of a non-whitespace character in [<code>position</code>, <code>bound</code>), or <code>NOT_FOUND</code> if none can be found
+ */
+ public int findNonWhitespaceForwardInAnyPartition(int position, int bound) {
+ return scanForward(position, bound, fNonWS);
+ }
+
+ /**
+ * Finds the highest position in <code>fDocument</code> such that the position is &lt;= <code>position</code>
+ * and &gt; <code>bound</code> and <code>Character.isWhitespace(fDocument.getChar(pos))</code> evaluates to <code>false</code>
+ * and the position is in the default partition.
+ *
+ * @param position the first character position in <code>fDocument</code> to be considered
+ * @param bound the first position in <code>fDocument</code> to not consider any more, with <code>bound</code> &lt; <code>position</code>, or <code>UNBOUND</code>
+ * @return the highest position of a non-whitespace character in (<code>bound</code>, <code>position</code>] that resides in a C partition, or <code>NOT_FOUND</code> if none can be found
+ */
+ public int findNonWhitespaceBackward(int position, int bound) {
+ return scanBackward(position, bound, fNonWSDefaultPart);
+ }
+
+ /**
+ * Finds the lowest position <code>p</code> in <code>fDocument</code> such that <code>start</code> &lt;= p &lt;
+ * <code>bound</code> and <code>condition.stop(fDocument.getChar(p), p)</code> evaluates to <code>true</code>.
+ *
+ * @param start the first character position in <code>fDocument</code> to be considered
+ * @param bound the first position in <code>fDocument</code> to not consider any more, with <code>bound</code> &gt; <code>start</code>, or <code>UNBOUND</code>
+ * @param condition the <code>StopCondition</code> to check
+ * @return the lowest position in [<code>start</code>, <code>bound</code>) for which <code>condition</code> holds, or <code>NOT_FOUND</code> if none can be found
+ */
+ public int scanForward(int start, int bound, StopCondition condition) {
+ Assert.isLegal(start >= 0);
+
+ if (bound == UNBOUND)
+ bound= fDocument.getLength();
+
+ Assert.isLegal(bound <= fDocument.getLength());
+
+ try {
+ fPos= start;
+ while (fPos < bound) {
+
+ fChar= fDocument.getChar(fPos);
+ if (condition.stop(fChar, fPos, true))
+ return fPos;
+
+ fPos= condition.nextPosition(fPos, true);
+ }
+ } catch (BadLocationException e) {
+ }
+ return NOT_FOUND;
+ }
+
+
+ /**
+ * Finds the lowest position in <code>fDocument</code> such that the position is &gt;= <code>position</code>
+ * and &lt; <code>bound</code> and <code>fDocument.getChar(position) == ch</code> evaluates to <code>true</code>
+ * and the position is in the default partition.
+ *
+ * @param position the first character position in <code>fDocument</code> to be considered
+ * @param bound the first position in <code>fDocument</code> to not consider any more, with <code>bound</code> &gt; <code>position</code>, or <code>UNBOUND</code>
+ * @param ch the <code>char</code> to search for
+ * @return the lowest position of <code>ch</code> in (<code>bound</code>, <code>position</code>] that resides in a C partition, or <code>NOT_FOUND</code> if none can be found
+ */
+ public int scanForward(int position, int bound, char ch) {
+ return scanForward(position, bound, new CharacterMatch(ch));
+ }
+
+ /**
+ * Finds the lowest position in <code>fDocument</code> such that the position is &gt;= <code>position</code>
+ * and &lt; <code>bound</code> and <code>fDocument.getChar(position) == ch</code> evaluates to <code>true</code> for at least one
+ * ch in <code>chars</code> and the position is in the default partition.
+ *
+ * @param position the first character position in <code>fDocument</code> to be considered
+ * @param bound the first position in <code>fDocument</code> to not consider any more, with <code>bound</code> &gt; <code>position</code>, or <code>UNBOUND</code>
+ * @param chars an array of <code>char</code> to search for
+ * @return the lowest position of a non-whitespace character in [<code>position</code>, <code>bound</code>) that resides in a C partition, or <code>NOT_FOUND</code> if none can be found
+ */
+ public int scanForward(int position, int bound, char[] chars) {
+ return scanForward(position, bound, new CharacterMatch(chars));
+ }
+
+ /**
+ * Finds the highest position <code>p</code> in <code>fDocument</code> such that <code>bound</code> &lt; <code>p</code> &lt;= <code>start</code>
+ * and <code>condition.stop(fDocument.getChar(p), p)</code> evaluates to <code>true</code>.
+ *
+ * @param start the first character position in <code>fDocument</code> to be considered
+ * @param bound the first position in <code>fDocument</code> to not consider any more, with <code>bound</code> &lt; <code>start</code>, or <code>UNBOUND</code>
+ * @param condition the <code>StopCondition</code> to check
+ * @return the highest position in (<code>bound</code>, <code>start</code> for which <code>condition</code> holds, or <code>NOT_FOUND</code> if none can be found
+ */
+ public int scanBackward(int start, int bound, StopCondition condition) {
+ if (bound == UNBOUND)
+ bound= -1;
+
+ Assert.isLegal(bound >= -1);
+ Assert.isLegal(start < fDocument.getLength() );
+
+ try {
+ fPos= start;
+ while (fPos > bound) {
+
+ fChar= fDocument.getChar(fPos);
+ if (condition.stop(fChar, fPos, false))
+ return fPos;
+
+ fPos= condition.nextPosition(fPos, false);
+ }
+ } catch (BadLocationException e) {
+ }
+ return NOT_FOUND;
+ }
+
+ /**
+ * Finds the highest position in <code>fDocument</code> such that the position is &lt;= <code>position</code>
+ * and &gt; <code>bound</code> and <code>fDocument.getChar(position) == ch</code> evaluates to <code>true</code>
+ * and the position is in the default partition.
+ *
+ * @param position the first character position in <code>fDocument</code> to be considered
+ * @param bound the first position in <code>fDocument</code> to not consider any more, with <code>bound</code> &lt; <code>position</code>, or <code>UNBOUND</code>
+ * @param ch the <code>char</code> to search for
+ * @return the highest position of one element in <code>chars</code> in (<code>bound</code>, <code>position</code>] that resides in a C partition, or <code>NOT_FOUND</code> if none can be found
+ */
+ public int scanBackward(int position, int bound, char ch) {
+ return scanBackward(position, bound, new CharacterMatch(ch));
+ }
+
+ /**
+ * Finds the highest position in <code>fDocument</code> such that the position is &lt;= <code>position</code>
+ * and &gt; <code>bound</code> and <code>fDocument.getChar(position) == ch</code> evaluates to <code>true</code> for at least one
+ * ch in <code>chars</code> and the position is in the default partition.
+ *
+ * @param position the first character position in <code>fDocument</code> to be considered
+ * @param bound the first position in <code>fDocument</code> to not consider any more, with <code>bound</code> &lt; <code>position</code>, or <code>UNBOUND</code>
+ * @param chars an array of <code>char</code> to search for
+ * @return the highest position of one element in <code>chars</code> in (<code>bound</code>, <code>position</code>] that resides in a C partition, or <code>NOT_FOUND</code> if none can be found
+ */
+ public int scanBackward(int position, int bound, char[] chars) {
+ return scanBackward(position, bound, new CharacterMatch(chars));
+ }
+
+ /**
+ * Checks whether <code>position</code> resides in a default (C) partition of <code>fDocument</code>.
+ *
+ * @param position the position to be checked
+ * @return <code>true</code> if <code>position</code> is in the default partition of <code>fDocument</code>, <code>false</code> otherwise
+ */
+ public boolean isDefaultPartition(int position) {
+ String type = getPartition(position).getType();
+ return fPartition.equals(type);
+// || STPPartitionScanner.STP_PROBE.equals(type);
+ }
+
+ /**
+ * Returns the partition at <code>position</code>.
+ *
+ * @param position the position to get the partition for
+ * @return the partition at <code>position</code> or a dummy zero-length
+ * partition if accessing the document fails
+ */
+ private ITypedRegion getPartition(int position) {
+ if (!contains(fCachedPartition, position)) {
+ Assert.isTrue(position >= 0);
+ Assert.isTrue(position <= fDocument.getLength());
+
+ try {
+ fCachedPartition= TextUtilities.getPartition(fDocument, fPartitioning, position, false);
+ } catch (BadLocationException e) {
+ fCachedPartition= new TypedRegion(position, 0, "__no_partition_at_all"); //$NON-NLS-1$
+ }
+ }
+
+ return fCachedPartition;
+ }
+
+ /**
+ * Returns <code>true</code> if <code>region</code> contains <code>position</code>.
+ *
+ * @param region a region
+ * @param position an offset
+ * @return <code>true</code> if <code>region</code> contains <code>position</code>
+ */
+ private boolean contains(IRegion region, int position) {
+ int offset= region.getOffset();
+ return offset <= position && position < offset + region.getLength();
+ }
+
+ /**
+ * Checks if the line seems to be an open condition not followed by a block (i.e. an if, while,
+ * or for statement with just one following statement, see example below).
+ *
+ * <pre>
+ * if (condition)
+ * doStuff();
+ * </pre>
+ *
+ * <p>Algorithm: if the last non-WS, non-Comment code on the line is an if (condition), while (condition),
+ * for( expression), do, else, and there is no statement after that </p>
+ *
+ * @param position the insert position of the new character
+ * @param bound the lowest position to consider
+ * @return <code>true</code> if the code is a conditional statement or loop without a block, <code>false</code> otherwise
+ */
+ public boolean isBracelessBlockStart(int position, int bound) {
+ if (position < 1)
+ return false;
+
+ switch (previousToken(position, bound)) {
+ case TokenDO:
+ case TokenELSE:
+ return true;
+ case TokenRPAREN:
+ position= findOpeningPeer(fPos, STPHeuristicScanner.UNBOUND, LPAREN, RPAREN);
+ if (position > 0) {
+ switch (previousToken(position - 1, bound)) {
+ case TokenIF:
+ case TokenFOR:
+ case TokenFOREACH:
+ case TokenWHILE:
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Returns <code>true</code> if the document, when scanned backwards from <code>start</code>
+ * appears to contain a class instance creation, i.e. a possibly qualified name preceded by a
+ * <code>new</code> keyword. The <code>start</code> must be at the end of the type name, and
+ * before any generic signature or constructor parameter list. The heuristic will return
+ * <code>true</code> if <code>start</code> is at the following positions (|):
+ *
+ * <pre>
+ * new std::vector&lt;std::string&gt;|(10)
+ * new str_vector |(10)
+ * new / * comment * / str_vector |(10)
+ * </pre>
+ *
+ * but not the following:
+ *
+ * <pre>
+ * new std::vector&lt;std::string&gt;(10)|
+ * new std::vector&lt;std::string&gt;|(10)
+ * new vector (10)|
+ * vector |(10)
+ * </pre>
+ *
+ * @param start the position where the type name of the class instance creation supposedly ends
+ * @param bound the first position in <code>fDocument</code> to not consider any more, with
+ * <code>bound</code> &lt; <code>start</code>, or <code>UNBOUND</code>
+ * @return <code>true</code> if the current position looks like after the type name of a class
+ * instance creation
+ */
+ public boolean looksLikeClassInstanceCreationBackward(int start, int bound) {
+ int token= previousToken(start - 1, bound);
+ if (token == STPSymbols.TokenIDENT) { // type name
+ token= previousToken(getPosition(), bound);
+ while (token == STPSymbols.TokenDOUBLECOLON) { // qualification
+ token= previousToken(getPosition(), bound);
+ if (token != STPSymbols.TokenIDENT) // qualification name
+ return false;
+ token= previousToken(getPosition(), bound);
+ }
+ return token == STPSymbols.TokenNEW;
+ }
+ return false;
+ }
+
+ /**
+ * Returns <code>true</code> if the document, when scanned backwards from <code>start</code>
+ * appears to contain a field reference, i.e. a (optional) name preceded by a <code>.</code>
+ * or <code>-&gt;</code> or <code>::</code>.
+ *
+ * @param start the position after the field reference operator.
+ * @param bound the first position in <code>fDocument</code> to not consider any more, with
+ * <code>bound</code> &lt; <code>start</code>, or <code>UNBOUND</code>
+ * @return <code>true</code> if the current position looks like a field reference
+ */
+ public boolean looksLikeFieldReferenceBackward(int start, int bound) {
+ int token= previousToken(start - 1, bound);
+ if (token == STPSymbols.TokenIDENT) { // field name
+ token= previousToken(getPosition(), bound);
+ }
+ if (token == STPSymbols.TokenDOT) {
+ return true;
+ }
+ if (token == STPSymbols.TokenARROW) {
+ return true;
+ } else if (token == STPSymbols.TokenDOUBLECOLON) {
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Returns <code>true</code> if the document, when scanned backwards from <code>start</code>
+ * appears to be a composite type (class, struct, union) or enum definition. Examples:
+ *
+ * <pre>
+ * class A {
+ * struct A {
+ * class A : B {
+ * class A : virtual public B, protected C&lt;T&gt; {
+ * enum E {
+ * </pre>
+ *
+ * @param start the position of the opening brace.
+ * @param bound the first position in <code>fDocument</code> to not consider any more, with
+ * <code>bound</code> &lt; <code>start</code>, or <code>UNBOUND</code>
+ * @return <code>true</code> if the current position looks like a composite type definition
+ */
+ public boolean looksLikeCompositeTypeDefinitionBackward(int start, int bound) {
+ int token= previousToken(start - 1, bound);
+ switch (token) {
+ case STPSymbols.TokenSTRUCT:
+ case STPSymbols.TokenUNION:
+ case STPSymbols.TokenENUM:
+ return true; // anonymous
+ case STPSymbols.TokenIDENT:
+ token= previousToken(getPosition(), bound);
+ switch (token) {
+ case STPSymbols.TokenCLASS:
+ case STPSymbols.TokenSTRUCT:
+ case STPSymbols.TokenUNION:
+ case STPSymbols.TokenENUM:
+ return true; // no base-clause
+ default:
+ // backtrack
+ token= previousToken(start - 1, bound);
+ }
+ break;
+ default:
+ // backtrack
+ token= previousToken(start - 1, bound);
+ break;
+ }
+ // match base-clause
+ if (token == STPSymbols.TokenGREATERTHAN) {
+ findOpeningPeer(getPosition(), bound, '<', '>');
+ token= previousToken(getPosition(), bound);
+ if (token != STPSymbols.TokenLESSTHAN) {
+ return false;
+ }
+ token= previousToken(getPosition(), bound);
+ }
+ outerWhile: while (token == STPSymbols.TokenIDENT) {// type name or base type
+ token= previousToken(getPosition(), bound);
+ // match nested-name-specifier
+ while (token == STPSymbols.TokenCOLON) { // colon of qualification
+ token= previousToken(getPosition(), bound);
+ if (token != STPSymbols.TokenCOLON) { // second colon of qualification
+ break outerWhile;
+ }
+ token= previousToken(getPosition(), bound);
+ if (token != STPSymbols.TokenIDENT) // qualification name?
+ break;
+ token= previousToken(getPosition(), bound);
+ }
+ switch (token) {
+ case STPSymbols.TokenVIRTUAL:
+ token= previousToken(getPosition(), bound);
+ //$FALL-THROUGH$
+ case STPSymbols.TokenPUBLIC:
+ case STPSymbols.TokenPROTECTED:
+ case STPSymbols.TokenPRIVATE:
+ token= previousToken(getPosition(), bound);
+ if (token == STPSymbols.TokenVIRTUAL) {
+ token= previousToken(getPosition(), bound);
+ }
+ if (token == STPSymbols.TokenCOMMA) {
+ token= previousToken(getPosition(), bound);
+ if (token == STPSymbols.TokenGREATERTHAN) {
+ findOpeningPeer(getPosition(), bound, '<', '>');
+ token= previousToken(getPosition(), bound);
+ if (token != STPSymbols.TokenLESSTHAN) {
+ return false;
+ }
+ token= previousToken(getPosition(), bound);
+ }
+ continue; // another base type
+ }
+ if (token != STPSymbols.TokenCOLON) // colon after class def identifier
+ return false;
+ //$FALL-THROUGH$
+ case STPSymbols.TokenCOLON:
+ token= previousToken(getPosition(), bound);
+ break outerWhile;
+ case STPSymbols.TokenCOMMA:
+ token= previousToken(getPosition(), bound);
+ if (token == STPSymbols.TokenGREATERTHAN) {
+ findOpeningPeer(getPosition(), bound, '<', '>');
+ token= previousToken(getPosition(), bound);
+ if (token != STPSymbols.TokenLESSTHAN) {
+ return false;
+ }
+ token= previousToken(getPosition(), bound);
+ }
+ continue; // another base type
+ case STPSymbols.TokenIDENT:
+ break outerWhile;
+ default:
+ return false;
+ }
+ }
+ if (token != STPSymbols.TokenIDENT) {
+ return false;
+ }
+ token= previousToken(getPosition(), bound);
+ switch (token) {
+ case STPSymbols.TokenCLASS:
+ case STPSymbols.TokenSTRUCT:
+ case STPSymbols.TokenUNION:
+ case STPSymbols.TokenENUM: // enum is actually not valid here
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ /**
+ * A simplified interface to CHeuristicScanner's
+ * nextToken() and previousToken() methods.
+ */
+ public static class TokenStream {
+ private STPHeuristicScanner fScanner;
+ private int fPos;
+ private final int fDocumentLength;
+
+ public TokenStream(IDocument document, int startPos) {
+ fScanner = new STPHeuristicScanner(document);
+ fPos = startPos;
+ fDocumentLength = document.getLength();
+ }
+
+ public int nextToken() {
+ int result = fScanner.nextToken(fPos, fDocumentLength);
+ fPos = fScanner.getPosition();
+ return result;
+ }
+
+ public int previousToken() {
+ int result = fScanner.previousToken(fPos, 0);
+ fPos = fScanner.getPosition();
+ return result;
+ }
+ }
+}
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPIndenter.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPIndenter.java
new file mode 100644
index 0000000000..b65a9e53ec
--- /dev/null
+++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPIndenter.java
@@ -0,0 +1,2349 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2011, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ * Sergey Prigogin (Google)
+ * Anton Leherbauer (Wind River Systems)
+ * Red Hat Inc. - modified for use in SystemTap
+ *******************************************************************************/
+package org.eclipse.linuxtools.internal.systemtap.ui.ide.editors.stp;
+
+import static org.eclipse.linuxtools.internal.systemtap.ui.ide.editors.stp.STPHeuristicScanner.NOT_FOUND;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.ProjectScope;
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.preferences.DefaultScope;
+import org.eclipse.core.runtime.preferences.IPreferencesService;
+import org.eclipse.core.runtime.preferences.IScopeContext;
+import org.eclipse.core.runtime.preferences.InstanceScope;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.linuxtools.internal.systemtap.ui.ide.IDEPlugin;
+
+/**
+ * Uses the {@link org.eclipse.cdt.internal.ui.text.STPHeuristicScanner} to
+ * get the indentation level for a certain position in a document.
+ *
+ * <p>
+ * An instance holds some internal position in the document and is therefore
+ * not thread-safe.
+ * </p>
+ */
+public final class STPIndenter {
+ /**
+ * The CDT Core preferences.
+ */
+ private final class CorePrefs {
+ final boolean prefUseTabs;
+ final int prefTabSize;
+ final int prefIndentationSize;
+ final boolean prefArrayDimensionsDeepIndent;
+ final int prefArrayIndent;
+ final boolean prefArrayDeepIndent;
+ final boolean prefTernaryDeepAlign;
+ final int prefTernaryIndent;
+ final int prefCaseIndent;
+ final int prefCaseBlockIndent;
+ final int prefAssignmentIndent;
+ final int prefSimpleIndent;
+ final int prefBracketIndent;
+ final boolean prefMethodDeclDeepIndent;
+ final boolean prefMethodDeclFirstParameterDeepIndent;
+ final int prefMethodDeclIndent;
+ final boolean prefMethodCallDeepIndent;
+ final boolean prefMethodCallFirstParameterDeepIndent;
+ final int prefMethodCallIndent;
+ final boolean prefParenthesisDeepIndent;
+ final int prefParenthesisIndent;
+ final int prefBlockIndent;
+ final int prefMethodBodyIndent;
+ final int prefTypeIndent;
+ final int prefAccessSpecifierIndent;
+ final int prefAccessSpecifierExtraSpaces;
+ final int prefNamespaceBodyIndent;
+ final boolean prefIndentBracesForBlocks;
+ final boolean prefIndentBracesForArrays;
+ final boolean prefIndentBracesForMethods;
+ final boolean prefIndentBracesForTypes;
+ final int prefContinuationIndent;
+ final boolean prefHasTemplates;
+ final String prefTabChar;
+
+ private final IPreferencesService preferenceService;
+ private final IScopeContext[] preferenceContexts;
+ private final IProject fProject;
+
+ /**
+ * Returns the possibly project-specific core preference defined under <code>key</code>.
+ *
+ * @param key the key of the preference
+ * @return the value of the preference
+ */
+ private String getCoreFormatterOption(String key) {
+ return getCoreFormatterOption(key, null);
+ }
+
+ private String getCoreFormatterOption(String key, String defaultValue) {
+ return preferenceService.getString(IDEPlugin.PLUGIN_ID, key, defaultValue, preferenceContexts);
+ }
+
+ private int getCoreFormatterOption(String key, int defaultValue) {
+ return preferenceService.getInt(IDEPlugin.PLUGIN_ID, key, defaultValue, preferenceContexts);
+ }
+
+ CorePrefs(IProject project) {
+ preferenceService = Platform.getPreferencesService();
+ preferenceContexts = project != null ?
+ new IScopeContext[] { new ProjectScope(project.getProject()),
+ InstanceScope.INSTANCE, DefaultScope.INSTANCE } :
+ new IScopeContext[] { InstanceScope.INSTANCE, DefaultScope.INSTANCE };
+ fProject= project;
+ prefUseTabs= prefUseTabs();
+ prefTabSize= prefTabSize();
+ prefIndentationSize= prefIndentationSize();
+ prefArrayDimensionsDeepIndent= prefArrayDimensionsDeepIndent();
+ prefContinuationIndent= prefContinuationIndent();
+ prefBlockIndent= prefBlockIndent();
+ prefArrayIndent= prefArrayIndent();
+ prefArrayDeepIndent= prefArrayDeepIndent();
+ prefTernaryDeepAlign= false;
+ prefTernaryIndent= prefContinuationIndent();
+ prefCaseIndent= prefCaseIndent();
+ prefCaseBlockIndent= prefCaseBlockIndent();
+ prefAssignmentIndent= prefAssignmentIndent();
+ prefIndentBracesForBlocks= prefIndentBracesForBlocks();
+ prefSimpleIndent= prefSimpleIndent();
+ prefBracketIndent= prefBracketIndent();
+ prefMethodDeclDeepIndent= prefMethodDeclDeepIndent();
+ prefMethodDeclFirstParameterDeepIndent= prefMethodDeclFirstParameterDeepIndent();
+ prefMethodDeclIndent= prefMethodDeclIndent();
+ prefMethodCallDeepIndent= prefMethodCallDeepIndent();
+ prefMethodCallFirstParameterDeepIndent= prefMethodCallFirstParameterDeepIndent();
+ prefMethodCallIndent= prefMethodCallIndent();
+ prefParenthesisDeepIndent= prefParenthesisDeepIndent();
+ prefParenthesisIndent= prefParenthesisIndent();
+ prefMethodBodyIndent= prefMethodBodyIndent();
+ prefTypeIndent= prefTypeIndent();
+ prefAccessSpecifierIndent= prefAccessSpecifierIndent();
+ prefAccessSpecifierExtraSpaces= prefAccessSpecifierExtraSpaces();
+ prefNamespaceBodyIndent= prefNamespaceBodyIndent();
+ prefIndentBracesForArrays= prefIndentBracesForArrays();
+ prefIndentBracesForMethods= prefIndentBracesForMethods();
+ prefIndentBracesForTypes= prefIndentBracesForTypes();
+ prefHasTemplates= hasTemplates();
+ prefTabChar= getCoreFormatterOption(STPDefaultCodeFormatterConstants.FORMATTER_TAB_CHAR);
+ }
+
+ private boolean prefUseTabs() {
+ return !IDEPlugin.SPACE.equals(getCoreFormatterOption(STPDefaultCodeFormatterConstants.FORMATTER_TAB_CHAR));
+ }
+
+ private int prefTabSize() {
+ return CodeFormatterUtil.getTabWidth(fProject);
+ }
+
+ private int prefIndentationSize() {
+ return CodeFormatterUtil.getIndentWidth(fProject);
+ }
+
+ private boolean prefArrayDimensionsDeepIndent() {
+ return true; // sensible default, no formatter setting
+ }
+
+ private int prefArrayIndent() {
+ String option= getCoreFormatterOption(STPDefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_EXPRESSIONS_IN_INITIALIZER_LIST);
+ try {
+ if (STPDefaultCodeFormatterConstants.getIndentStyle(option) == STPDefaultCodeFormatterConstants.INDENT_BY_ONE)
+ return 1;
+ } catch (IllegalArgumentException e) {
+ // ignore and return default
+ }
+
+ return prefContinuationIndent(); // default
+ }
+
+ private boolean prefArrayDeepIndent() {
+ String option= getCoreFormatterOption(STPDefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_EXPRESSIONS_IN_INITIALIZER_LIST);
+ try {
+ return STPDefaultCodeFormatterConstants.getIndentStyle(option) == STPDefaultCodeFormatterConstants.INDENT_ON_COLUMN;
+ } catch (IllegalArgumentException e) {
+ // ignore and return default
+ }
+
+ return true;
+ }
+
+ private int prefCaseIndent() {
+ if (STPDefaultCodeFormatterConstants.TRUE.equals(getCoreFormatterOption(STPDefaultCodeFormatterConstants.FORMATTER_INDENT_SWITCHSTATEMENTS_COMPARE_TO_SWITCH)))
+ return 1;
+ else
+ return 0;
+ }
+
+ private int prefCaseBlockIndent() {
+ if (STPDefaultCodeFormatterConstants.TRUE.equals(getCoreFormatterOption(STPDefaultCodeFormatterConstants.FORMATTER_INDENT_SWITCHSTATEMENTS_COMPARE_TO_CASES)))
+ return 1;
+ else
+ return 0;
+ }
+
+ private int prefAssignmentIndent() {
+ return prefContinuationIndent();
+ }
+
+ private int prefSimpleIndent() {
+ if (prefIndentBracesForBlocks() && prefBlockIndent() == 0)
+ return 1;
+ else
+ return prefBlockIndent();
+ }
+
+ private int prefBracketIndent() {
+ return prefBlockIndent();
+ }
+
+ private boolean prefMethodDeclDeepIndent() {
+ String option= getCoreFormatterOption(STPDefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_PARAMETERS_IN_METHOD_DECLARATION);
+ try {
+ int indentStyle = STPDefaultCodeFormatterConstants.getIndentStyle(option);
+ return indentStyle == STPDefaultCodeFormatterConstants.INDENT_ON_COLUMN;
+ } catch (IllegalArgumentException e) {
+ // ignore and return default
+ }
+
+ return false;
+ }
+
+ private boolean prefMethodDeclFirstParameterDeepIndent() {
+ String option= getCoreFormatterOption(STPDefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_PARAMETERS_IN_METHOD_DECLARATION);
+ try {
+ int indentStyle = STPDefaultCodeFormatterConstants.getIndentStyle(option);
+ int wrappingStyle = STPDefaultCodeFormatterConstants.getWrappingStyle(option);
+ return indentStyle == STPDefaultCodeFormatterConstants.INDENT_ON_COLUMN &&
+ (wrappingStyle == STPDefaultCodeFormatterConstants.WRAP_COMPACT_FIRST_BREAK ||
+ wrappingStyle == STPDefaultCodeFormatterConstants.WRAP_ONE_PER_LINE);
+ } catch (IllegalArgumentException e) {
+ // ignore and return default
+ }
+
+ return false;
+ }
+
+ private int prefMethodDeclIndent() {
+ String option= getCoreFormatterOption(STPDefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_PARAMETERS_IN_METHOD_DECLARATION);
+ try {
+ if (STPDefaultCodeFormatterConstants.getIndentStyle(option) == STPDefaultCodeFormatterConstants.INDENT_BY_ONE)
+ return 1;
+ else
+ return prefContinuationIndent();
+ } catch (IllegalArgumentException e) {
+ // ignore and return default
+ }
+ return 1;
+ }
+
+ private boolean prefMethodCallDeepIndent() {
+ String option= getCoreFormatterOption(STPDefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_ARGUMENTS_IN_METHOD_INVOCATION);
+ try {
+ int indentStyle = STPDefaultCodeFormatterConstants.getIndentStyle(option);
+ return indentStyle == STPDefaultCodeFormatterConstants.INDENT_ON_COLUMN;
+ } catch (IllegalArgumentException e) {
+ // ignore and return default
+ }
+ return false; // sensible default
+ }
+
+ private boolean prefMethodCallFirstParameterDeepIndent() {
+ String option= getCoreFormatterOption(STPDefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_ARGUMENTS_IN_METHOD_INVOCATION);
+ try {
+ int indentStyle = STPDefaultCodeFormatterConstants.getIndentStyle(option);
+ int wrappingStyle = STPDefaultCodeFormatterConstants.getWrappingStyle(option);
+ return indentStyle == STPDefaultCodeFormatterConstants.INDENT_ON_COLUMN &&
+ (wrappingStyle == STPDefaultCodeFormatterConstants.WRAP_COMPACT_FIRST_BREAK ||
+ wrappingStyle == STPDefaultCodeFormatterConstants.WRAP_ONE_PER_LINE);
+ } catch (IllegalArgumentException e) {
+ // ignore and return default
+ }
+ return false; // sensible default
+ }
+
+ private int prefMethodCallIndent() {
+ String option= getCoreFormatterOption(STPDefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_ARGUMENTS_IN_METHOD_INVOCATION);
+ try {
+ if (STPDefaultCodeFormatterConstants.getIndentStyle(option) == STPDefaultCodeFormatterConstants.INDENT_BY_ONE)
+ return 1;
+ else
+ return prefContinuationIndent();
+ } catch (IllegalArgumentException e) {
+ // ignore and return default
+ }
+
+ return 1; // sensible default
+ }
+
+ private boolean prefParenthesisDeepIndent() {
+ // don't do parenthesis deep indentation
+// String option= getCoreFormatterOption(STPDefaultCodeFormatterConstants.FORMATTER_CONTINUATION_INDENTATION);
+// try {
+// return STPDefaultCodeFormatterConstants.getIndentStyle(option) == STPDefaultCodeFormatterConstants.INDENT_ON_COLUMN;
+// } catch (IllegalArgumentException e) {
+// // ignore and return default
+// }
+
+ return false;
+ }
+
+ private int prefParenthesisIndent() {
+ return prefContinuationIndent();
+ }
+
+ private int prefBlockIndent() {
+ String option= getCoreFormatterOption(STPDefaultCodeFormatterConstants.FORMATTER_INDENT_STATEMENTS_COMPARE_TO_BLOCK);
+ if (STPDefaultCodeFormatterConstants.FALSE.equals(option))
+ return 0;
+
+ return 1; // sensible default
+ }
+
+ private int prefMethodBodyIndent() {
+ if (STPDefaultCodeFormatterConstants.FALSE.equals(getCoreFormatterOption(STPDefaultCodeFormatterConstants.FORMATTER_INDENT_STATEMENTS_COMPARE_TO_BODY)))
+ return 0;
+
+ return 1; // sensible default
+ }
+
+ private int prefTypeIndent() {
+ String option= getCoreFormatterOption(STPDefaultCodeFormatterConstants.FORMATTER_INDENT_BODY_DECLARATIONS_COMPARE_TO_ACCESS_SPECIFIER);
+ if (STPDefaultCodeFormatterConstants.FALSE.equals(option))
+ return 0;
+
+ return 1; // sensible default
+ }
+
+ private int prefAccessSpecifierIndent() {
+ if (STPDefaultCodeFormatterConstants.TRUE.equals(getCoreFormatterOption(STPDefaultCodeFormatterConstants.FORMATTER_INDENT_ACCESS_SPECIFIER_COMPARE_TO_TYPE_HEADER)))
+ return 1;
+ else
+ return 0;
+ }
+
+ private int prefAccessSpecifierExtraSpaces() {
+ return getCoreFormatterOption(STPDefaultCodeFormatterConstants.FORMATTER_INDENT_ACCESS_SPECIFIER_EXTRA_SPACES, 0);
+ }
+
+ private int prefNamespaceBodyIndent() {
+ if (STPDefaultCodeFormatterConstants.TRUE.equals(getCoreFormatterOption(STPDefaultCodeFormatterConstants.FORMATTER_INDENT_BODY_DECLARATIONS_COMPARE_TO_NAMESPACE_HEADER)))
+ return prefBlockIndent();
+ else
+ return 0;
+ }
+
+ private boolean prefIndentBracesForBlocks() {
+ return STPDefaultCodeFormatterConstants.NEXT_LINE_SHIFTED.equals(getCoreFormatterOption(STPDefaultCodeFormatterConstants.FORMATTER_BRACE_POSITION_FOR_BLOCK));
+ }
+
+ private boolean prefIndentBracesForArrays() {
+ return STPDefaultCodeFormatterConstants.NEXT_LINE_SHIFTED.equals(getCoreFormatterOption(STPDefaultCodeFormatterConstants.FORMATTER_BRACE_POSITION_FOR_INITIALIZER_LIST));
+ }
+
+ private boolean prefIndentBracesForMethods() {
+ return STPDefaultCodeFormatterConstants.NEXT_LINE_SHIFTED.equals(getCoreFormatterOption(STPDefaultCodeFormatterConstants.FORMATTER_BRACE_POSITION_FOR_METHOD_DECLARATION));
+ }
+
+ private boolean prefIndentBracesForTypes() {
+ return STPDefaultCodeFormatterConstants.NEXT_LINE_SHIFTED.equals(getCoreFormatterOption(STPDefaultCodeFormatterConstants.FORMATTER_BRACE_POSITION_FOR_TYPE_DECLARATION));
+ }
+
+ private int prefContinuationIndent() {
+ try {
+ return Integer.parseInt(getCoreFormatterOption(STPDefaultCodeFormatterConstants.FORMATTER_CONTINUATION_INDENTATION));
+ } catch (NumberFormatException e) {
+ // ignore and return default
+ }
+
+ return 2; // sensible default
+ }
+
+ private boolean hasTemplates() {
+ return true;
+ }
+ }
+
+ /** The document being scanned. */
+ private final IDocument fDocument;
+ /** The indentation accumulated by <code>findReferencePosition</code>. */
+ private int fIndent;
+ /** Extra spaces to add on top of fIndent */
+ private int fExtraSpaces;
+ /**
+ * The absolute (character-counted) indentation offset for special cases
+ * (method definitions, array initializers)
+ */
+ private int fAlign;
+ /** The stateful scan position for the indentation methods. */
+ private int fPosition;
+ /** The previous position. */
+ private int fPreviousPos;
+ /** The most recent token. */
+ private int fToken;
+ /** The line of <code>fPosition</code>. */
+ private int fLine;
+ /**
+ * The scanner we will use to scan the document. It has to be installed
+ * on the same document as the one we get.
+ */
+ private final STPHeuristicScanner fScanner;
+ /**
+ * The CDT Core preferences.
+ */
+ private final CorePrefs fPrefs;
+
+ /**
+ * Creates a new instance.
+ *
+ * @param document the document to scan
+ * @param scanner the {@link STPHeuristicScanner} to be used for scanning
+ * the document. It must be installed on the same <code>IDocument</code>.
+ */
+ public STPIndenter(IDocument document, STPHeuristicScanner scanner) {
+ this(document, scanner, null);
+ }
+
+ /**
+ * Creates a new instance.
+ *
+ * @param document the document to scan
+ * @param scanner the {@link STPHeuristicScanner} to be used for scanning
+ * the document. It must be installed on the same
+ * <code>IDocument</code>.
+ * @param project the C/C++ project to get the formatter preferences from, or
+ * <code>null</code> to use the workspace settings
+ */
+ public STPIndenter(IDocument document, STPHeuristicScanner scanner, IProject project) {
+ Assert.isNotNull(document);
+ Assert.isNotNull(scanner);
+ fDocument= document;
+ fScanner= scanner;
+ fPrefs= new CorePrefs(project);
+ }
+
+ /**
+ * Computes the indentation at the reference point of <code>position</code>.
+ *
+ * @param offset the offset in the document
+ * @return a String which reflects the indentation at the line in which the
+ * reference position to <code>offset</code> resides, or <code>null</code>
+ * if it cannot be determined
+ */
+ public StringBuilder getReferenceIndentation(int offset) {
+ return getReferenceIndentation(offset, false);
+ }
+
+ /**
+ * Computes the indentation at the reference point of <code>position</code>.
+ *
+ * @param offset the offset in the document
+ * @param assumeOpeningBrace <code>true</code> if an opening brace should be assumed
+ * @return a String which reflects the indentation at the line in which the
+ * reference position to <code>offset</code> resides, or <code>null</code>
+ * if it cannot be determined
+ */
+ private StringBuilder getReferenceIndentation(int offset, boolean assumeOpeningBrace) {
+ int unit= findReferencePosition(offset,
+ assumeOpeningBrace ? STPSymbols.TokenLBRACE : peekToken(offset));
+
+ // if we were unable to find anything, return null
+ if (unit == NOT_FOUND)
+ return null;
+
+ return getLeadingWhitespace(unit);
+ }
+
+ /**
+ * Computes the indentation at <code>offset</code>.
+ *
+ * @param offset the offset in the document
+ * @return a String which reflects the correct indentation for the line in
+ * which offset resides, or <code>null</code> if it cannot be
+ * determined
+ */
+ public StringBuilder computeIndentation(int offset) {
+ return computeIndentation(offset, false);
+ }
+
+ /**
+ * Computes the indentation at <code>offset</code>.
+ *
+ * @param offset the offset in the document
+ * @param assumeOpeningBrace <code>true</code> if an opening brace should be assumed
+ * @return a String which reflects the correct indentation for the line in
+ * which offset resides, or <code>null</code> if it cannot be
+ * determined
+ */
+ public StringBuilder computeIndentation(int offset, boolean assumeOpeningBrace) {
+ StringBuilder reference= getReferenceIndentation(offset, assumeOpeningBrace);
+
+ // handle special alignment
+ if (fAlign != NOT_FOUND) {
+ try {
+ // a special case has been detected.
+ IRegion line= fDocument.getLineInformationOfOffset(fAlign);
+ int lineOffset= line.getOffset();
+ return createIndent(lineOffset, fAlign, false);
+ } catch (BadLocationException e) {
+ return null;
+ }
+ }
+
+ if (reference == null)
+ return null;
+
+ // Add additional indent
+ return createReusingIndent(reference, fIndent, fExtraSpaces);
+ }
+
+ /**
+ * Computes the indentation for a continuation line at <code>offset</code>.
+ *
+ * @param offset the offset in the document
+ * @return a StringBuilder which reflects the correct indentation for
+ * the line in which offset resides, or <code>null</code> if it cannot be
+ * determined.
+ * @throws BadLocationException
+ */
+ public StringBuilder computeContinuationLineIndentation(int offset) throws BadLocationException {
+ StringBuilder reference= getLeadingWhitespace(offset);
+ IRegion line= fDocument.getLineInformationOfOffset(offset);
+ String string= fDocument.get(line.getOffset(), offset - line.getOffset());
+ if (string.trim().isEmpty())
+ return reference;
+ // Add additional indent
+ return createReusingIndent(reference, fPrefs.prefContinuationIndent, 0);
+ }
+
+ /**
+ * Computes the length of a <code>CharacterSequence</code>, counting
+ * a tab character as the size until the next tab stop and every other
+ * character as one.
+ *
+ * @param indent the string to measure
+ * @return the visual length in characters
+ */
+ private int computeVisualLength(CharSequence indent) {
+ final int tabSize= fPrefs.prefTabSize;
+ int length= 0;
+ for (int i= 0; i < indent.length(); i++) {
+ char ch= indent.charAt(i);
+ switch (ch) {
+ case '\t':
+ if (tabSize > 0) {
+ int reminder= length % tabSize;
+ length += tabSize - reminder;
+ }
+ break;
+ case ' ':
+ length++;
+ break;
+ }
+ }
+ return length;
+ }
+
+ /**
+ * Strips any characters off the end of <code>reference</code> that exceed
+ * <code>indentLength</code>.
+ *
+ * @param reference the string to measure
+ * @param indentLength the maximum visual indentation length
+ * @return the stripped <code>reference</code>
+ */
+ private StringBuilder stripExceedingChars(StringBuilder reference, int indentLength) {
+ final int tabSize= fPrefs.prefTabSize;
+ int measured= 0;
+ int chars= reference.length();
+ int i= 0;
+ for (; measured < indentLength && i < chars; i++) {
+ char ch= reference.charAt(i);
+ switch (ch) {
+ case '\t':
+ if (tabSize > 0) {
+ int reminder= measured % tabSize;
+ measured += tabSize - reminder;
+ }
+ break;
+ case ' ':
+ measured++;
+ break;
+ }
+ }
+ int deleteFrom= measured > indentLength ? i - 1 : i;
+
+ return reference.delete(deleteFrom, chars);
+ }
+
+ /**
+ * Returns the indentation of the line at <code>offset</code> as a
+ * <code>StringBuilder</code>. If the offset is not valid, the empty string
+ * is returned.
+ *
+ * @param offset the offset in the document
+ * @return the indentation (leading whitespace) of the line in which
+ * <code>offset</code> is located
+ */
+ private StringBuilder getLeadingWhitespace(int offset) {
+ StringBuilder indent= new StringBuilder();
+ try {
+ IRegion line= fDocument.getLineInformationOfOffset(offset);
+ int lineOffset= line.getOffset();
+ int nonWS= fScanner.findNonWhitespaceForwardInAnyPartition(lineOffset, lineOffset + line.getLength());
+ indent.append(fDocument.get(lineOffset, nonWS - lineOffset));
+ return indent;
+ } catch (BadLocationException e) {
+ return indent;
+ }
+ }
+
+ /**
+ * Creates an indentation string of the length indent - start, consisting of
+ * the content in <code>fDocument</code> in the range [start, indent),
+ * with every character replaced by a space except for tabs, which are kept
+ * as such.
+ * <p>
+ * If <code>convertSpaceRunsToTabs</code> is <code>true</code>, every
+ * run of the number of spaces that make up a tab are replaced by a tab
+ * character. If it is not set, no conversion takes place, but tabs in the
+ * original range are still copied verbatim.
+ * </p>
+ *
+ * @param start the start of the document region to copy the indent from
+ * @param indent the exclusive end of the document region to copy the indent
+ * from
+ * @param convertSpaceRunsToTabs whether to convert consecutive runs of
+ * spaces to tabs
+ * @return the indentation corresponding to the document content specified
+ * by <code>start</code> and <code>indent</code>
+ */
+ private StringBuilder createIndent(int start, final int indent, final boolean convertSpaceRunsToTabs) {
+ final boolean convertTabs= fPrefs.prefUseTabs && convertSpaceRunsToTabs;
+ final int tabLen= fPrefs.prefTabSize;
+ final StringBuilder ret= new StringBuilder();
+ try {
+ int spaces= 0;
+ while (start < indent) {
+ char ch= fDocument.getChar(start);
+ if (ch == '\t') {
+ ret.append('\t');
+ spaces= 0;
+ } else if (convertTabs) {
+ spaces++;
+ if (spaces == tabLen) {
+ ret.append('\t');
+ spaces= 0;
+ }
+ } else {
+ ret.append(' ');
+ }
+
+ start++;
+ }
+ // remainder
+ while (spaces-- > 0)
+ ret.append(' ');
+ } catch (BadLocationException e) {
+ }
+
+ return ret;
+ }
+
+ /**
+ * Creates a string with a visual length of the given
+ * <code>indentationSize</code>.
+ *
+ * @param buffer the original indent to reuse if possible
+ * @param additional the additional indentation units to add or subtract to
+ * reference
+ * @param extraSpaces additional spaces to add to indentation.
+ * @return the modified <code>buffer</code> reflecting the indentation
+ * adapted to <code>additional</code>
+ */
+ public StringBuilder createReusingIndent(StringBuilder buffer, int additional, int extraSpaces) {
+ int refLength= computeVisualLength(buffer);
+ int addLength= fPrefs.prefIndentationSize * additional + extraSpaces; // may be < 0
+ int totalLength= Math.max(0, refLength + addLength);
+
+ // copy the reference indentation for the indent up to the last tab
+ // stop within the maxCopy area
+ int minLength= Math.min(totalLength, refLength);
+ int tabSize= fPrefs.prefTabSize;
+ int maxCopyLength= tabSize > 0 ? minLength - minLength % tabSize : minLength; // maximum indent to copy
+ stripExceedingChars(buffer, maxCopyLength);
+
+ // add additional indent
+ int missing= totalLength - maxCopyLength;
+ final int tabs, spaces;
+ if (IDEPlugin.SPACE.equals(fPrefs.prefTabChar)) {
+ tabs= 0;
+ spaces= missing;
+ } else {
+ tabs= tabSize > 0 ? missing / tabSize : 0;
+ spaces= tabSize > 0 ? missing % tabSize : missing;
+ }
+ for (int i= 0; i < tabs; i++)
+ buffer.append('\t');
+ for (int i= 0; i < spaces; i++)
+ buffer.append(' ');
+ return buffer;
+ }
+
+ /**
+ * Returns relative indent of continuation lines.
+ * @return a number of indentation units.
+ */
+ public int getContinuationLineIndent() {
+ return fPrefs.prefContinuationIndent;
+ }
+
+ /**
+ * Returns the reference position regarding to indentation for <code>offset</code>,
+ * or {@link STPHeuristicScanner#NOT_FOUND NOT_FOUND}. This method calls
+ * {@link #findReferencePosition(int, int) findReferencePosition(offset, nextChar)} where
+ * <code>nextChar</code> is the next character after <code>offset</code>.
+ *
+ * @param offset the offset for which the reference is computed
+ * @return the reference statement relative to which <code>offset</code>
+ * should be indented, or {@link STPHeuristicScanner#NOT_FOUND NOT_FOUND}
+ */
+ public int findReferencePosition(int offset) {
+ return findReferencePosition(offset, peekToken(offset));
+ }
+
+ /**
+ * Peeks the next token in the document that comes after <code>offset</code>
+ * on the same line as <code>offset</code>.
+ *
+ * @param offset the offset into document
+ * @return the token symbol of the next element, or TokenEOF if there is none
+ */
+ private int peekToken(int offset) {
+ if (offset < fDocument.getLength()) {
+ try {
+ IRegion line= fDocument.getLineInformationOfOffset(offset);
+ int lineEnd= line.getOffset() + line.getLength();
+ int next= fScanner.nextToken(offset, lineEnd);
+ return next;
+ } catch (BadLocationException e) {
+ }
+ }
+ return STPSymbols.TokenEOF;
+ }
+
+ /**
+ * Peeks the second next token in the document that comes after <code>offset</code>
+ * on the same line as <code>offset</code>.
+ *
+ * @param offset the offset into document
+ * @return the token symbol of the second next element, or TokenEOF if there is none
+ */
+ private int peekSecondToken(int offset) {
+ if (offset < fDocument.getLength()) {
+ try {
+ IRegion line= fDocument.getLineInformationOfOffset(offset);
+ int lineEnd= line.getOffset() + line.getLength();
+ fScanner.nextToken(offset, lineEnd);
+ int next = fScanner.nextToken(fScanner.getPosition(), lineEnd);
+ return next;
+ } catch (BadLocationException e) {
+ }
+ }
+ return STPSymbols.TokenEOF;
+ }
+
+ /**
+ * Returns the reference position regarding to indentation for <code>position</code>,
+ * or {@link STPHeuristicScanner#NOT_FOUND NOT_FOUND}.
+ *
+ * <p>If <code>peekNextChar</code> is <code>true</code>, the next token after
+ * <code>offset</code> is read and taken into account when computing the
+ * indentation. Currently, if the next token is the first token on the line
+ * (i.e. only preceded by whitespace), the following tokens are specially
+ * handled:
+ * <ul>
+ * <li><code>switch</code> labels are indented relative to the switch block</li>
+ * <li>opening curly braces are aligned correctly with the introducing code</li>
+ * <li>closing curly braces are aligned properly with the introducing code of
+ * the matching opening brace</li>
+ * <li>closing parenthesis' are aligned with their opening peer</li>
+ * <li>the <code>else</code> keyword is aligned with its <code>if</code>, anything
+ * else is aligned normally (i.e. with the base of any introducing statements).</li>
+ * <li>if there is no token on the same line after <code>offset</code>, the indentation
+ * is the same as for an <code>else</code> keyword</li>
+ * </ul>
+ *
+ * @param offset the offset for which the reference is computed
+ * @param nextToken the next token to assume in the document
+ * @return the reference statement relative to which <code>offset</code>
+ * should be indented, or {@link STPHeuristicScanner#NOT_FOUND NOT_FOUND}
+ */
+ public int findReferencePosition(int offset, int nextToken) {
+ boolean danglingElse= false;
+ boolean cancelIndent= false; // If set to true, fIndent is ignored.
+ int extraIndent= 0; // Can be either positive or negative.
+ MatchMode matchMode = MatchMode.REGULAR;
+
+ // Account for un-indentation characters already typed in, but after position.
+ // If they are on a line by themselves, the indentation gets adjusted accordingly.
+ //
+ // Also account for a dangling else.
+ if (offset < fDocument.getLength()) {
+ try {
+ IRegion line= fDocument.getLineInformationOfOffset(offset);
+ int lineOffset= line.getOffset();
+ int prevPos= Math.max(offset - 1, 0);
+ boolean isFirstTokenOnLine=
+ fDocument.get(lineOffset, prevPos + 1 - lineOffset).trim().length() == 0;
+ int prevToken= fScanner.previousToken(prevPos, STPHeuristicScanner.UNBOUND);
+ boolean bracelessBlockStart= fScanner.isBracelessBlockStart(prevPos, STPHeuristicScanner.UNBOUND);
+
+ switch (nextToken) {
+ case STPSymbols.TokenELSE:
+ danglingElse= true;
+ break;
+
+ case STPSymbols.TokenCASE:
+ case STPSymbols.TokenDEFAULT:
+ if (isFirstTokenOnLine)
+ matchMode = MatchMode.MATCH_CASE;
+ break;
+
+ case STPSymbols.TokenPUBLIC:
+ case STPSymbols.TokenPROTECTED:
+ case STPSymbols.TokenPRIVATE:
+ if (isFirstTokenOnLine && peekSecondToken(offset) != STPSymbols.TokenIDENT)
+ matchMode = MatchMode.MATCH_ACCESS_SPECIFIER;
+ break;
+
+ case STPSymbols.TokenLBRACE: // for opening-brace-on-new-line style
+ if (bracelessBlockStart) {
+ extraIndent= fPrefs.prefIndentBracesForBlocks ? 0 : -1;
+ } else if (prevToken == STPSymbols.TokenCOLON && !fPrefs.prefIndentBracesForBlocks) {
+ extraIndent= -1;
+ } else if ((prevToken == STPSymbols.TokenEQUAL || prevToken == STPSymbols.TokenRBRACKET) &&
+ !fPrefs.prefIndentBracesForArrays) {
+ cancelIndent= true;
+ } else if ((prevToken == STPSymbols.TokenRPAREN || prevToken == STPSymbols.TokenCONST) && fPrefs.prefIndentBracesForMethods) {
+ extraIndent= 1;
+ } else if (prevToken == STPSymbols.TokenIDENT) {
+ if (fPrefs.prefIndentBracesForTypes) {
+ extraIndent= 1;
+ }
+ int pos = fPosition;
+ fPosition = offset;
+ if (matchTypeDeclaration() != NOT_FOUND) {
+ matchMode = MatchMode.MATCH_TYPE_DECLARATION;
+ }
+ fPosition = pos;
+ }
+ break;
+
+ case STPSymbols.TokenRBRACE: // closing braces get unindented
+ if (isFirstTokenOnLine || prevToken != STPSymbols.TokenLBRACE)
+ matchMode = MatchMode.MATCH_BRACE;
+ break;
+
+ case STPSymbols.TokenRPAREN:
+ if (isFirstTokenOnLine)
+ matchMode = MatchMode.MATCH_PAREN;
+ break;
+ }
+ } catch (BadLocationException e) {
+ }
+ } else {
+ // Don't assume an else could come if we are at the end of file.
+ danglingElse= false;
+ }
+
+ int ref= findReferencePosition(offset, danglingElse, matchMode);
+ if (cancelIndent) {
+ fIndent = 0;
+ } else if (extraIndent > 0) {
+ fAlign= NOT_FOUND;
+ fIndent += extraIndent;
+ } else {
+ fIndent += extraIndent;
+ }
+ return ref;
+ }
+
+ /**
+ * Enumeration used by {@link #findReferencePosition(int, boolean, MatchMode)} method.
+ */
+ public enum MatchMode {
+ /**
+ * The reference position should be returned based on the regular code analysis.
+ */
+ REGULAR,
+ /**
+ * The position of the matching brace should be returned instead of doing code analysis.
+ */
+ MATCH_BRACE,
+ /**
+ * The position of the matching parenthesis should be returned instead of doing code
+ * analysis.
+ */
+ MATCH_PAREN,
+ /**
+ * The position of a switch statement reference should be returned (either an earlier case
+ * statement or the switch block brace).
+ */
+ MATCH_CASE,
+ /**
+ * The position of a class body reference should be returned (either an earlier
+ * public/protected/private or the class body brace).
+ */
+ MATCH_ACCESS_SPECIFIER,
+ /**
+ * The position of a class declaration should be returned.
+ */
+ MATCH_TYPE_DECLARATION
+ }
+
+ /**
+ * Returns the reference position regarding to indentation for <code>position</code>,
+ * or {@link STPHeuristicScanner#NOT_FOUND NOT_FOUND}. <code>fIndent</code> will contain
+ * the relative indentation (in indentation units, not characters) after the call. If there is
+ * a special alignment (e.g. for a method declaration where parameters should be aligned),
+ * <code>fAlign</code> will contain the absolute position of the alignment reference
+ * in <code>fDocument</code>, otherwise <code>fAlign</code> is set to
+ * {@link STPHeuristicScanner#NOT_FOUND}.
+ *
+ * @param offset the offset for which the reference is computed
+ * @param danglingElse whether a dangling else should be assumed at <code>position</code>
+ * @param matchMode determines what kind of reference position should be returned.
+ * See {@link MatchMode}.
+ * @return the reference statement relative to which <code>position</code>
+ * should be indented, or {@link STPHeuristicScanner#NOT_FOUND}
+ */
+ public int findReferencePosition(int offset, boolean danglingElse, MatchMode matchMode) {
+ fIndent= 0; // The indentation modification
+ fExtraSpaces= 0;
+ fAlign= NOT_FOUND;
+ fPosition= offset;
+
+ // Forward cases.
+ // An unindentation happens sometimes if the next token is special, namely on braces,
+ // parens and case labels align braces, but handle the case where we align with the method
+ // declaration start instead of the opening brace.
+ switch (matchMode) {
+ case MATCH_BRACE:
+ if (skipScope(STPSymbols.TokenLBRACE, STPSymbols.TokenRBRACE)) {
+ try {
+ // Align with the opening brace that is on a line by its own
+ int lineOffset= fDocument.getLineOffset(fLine);
+ if (lineOffset <= fPosition &&
+ fDocument.get(lineOffset, fPosition - lineOffset).trim().isEmpty()) {
+ return fPosition;
+ }
+ } catch (BadLocationException e) {
+ // Concurrent modification - walk default path
+ }
+ // If the opening brace is not on the start of the line, skip to the start.
+ int pos= skipToStatementStart(true, true);
+ fIndent= 0; // indent is aligned with reference position
+ return pos;
+ } else {
+ // If we can't find the matching brace, the heuristic is to unindent
+ // by one against the normal position
+ int pos= findReferencePosition(offset, danglingElse, MatchMode.REGULAR);
+ fIndent--;
+ return pos;
+ }
+
+ case MATCH_PAREN:
+ // Align parentheses.
+ if (skipScope(STPSymbols.TokenLPAREN, STPSymbols.TokenRPAREN)) {
+ return fPosition;
+ } else {
+ // If we can't find the matching paren, the heuristic is to unindent by one
+ // against the normal position.
+ int pos= findReferencePosition(offset, danglingElse, MatchMode.REGULAR);
+ fIndent--;
+ return pos;
+ }
+
+ case MATCH_CASE:
+ // The only reliable way to get case labels aligned (due to many different styles of
+ // using braces in a block) is to go for another case statement, or the scope opening
+ // brace.
+ return matchCaseAlignment();
+
+ case MATCH_ACCESS_SPECIFIER:
+ // The only reliable way to get access specifiers aligned (due to many different styles
+ // of using braces in a block) is to go for another access specifier, or the scope
+ // opening brace.
+ return matchAccessSpecifierAlignment();
+
+ case MATCH_TYPE_DECLARATION:
+ return matchTypeDeclaration();
+
+ case REGULAR:
+ break;
+ }
+
+ if (peekToken(offset) == STPSymbols.TokenCOLON) {
+ int pos= fPosition;
+ if (looksLikeTypeInheritanceDecl()) {
+ fIndent = fPrefs.prefContinuationIndent;
+ return fPosition;
+ }
+ fPosition = pos;
+ }
+
+ nextToken();
+ // Skip access specifiers
+ while (fToken == STPSymbols.TokenCOLON && isAccessSpecifier()) {
+ nextToken();
+ }
+
+ int line= fLine;
+ switch (fToken) {
+ case STPSymbols.TokenGREATERTHAN:
+ case STPSymbols.TokenRBRACE:
+ // Skip the block and fall through.
+ // If we can't complete the scope, reset the scan position
+ int pos= fPosition;
+ if (!skipScope())
+ fPosition= pos;
+ return skipToStatementStart(danglingElse, false);
+
+ case STPSymbols.TokenSEMICOLON:
+ // This is the 90% case: after a statement block
+ // the end of the previous statement / block previous.end
+ // search to the end of the statement / block before the previous;
+ // the token just after that is previous.start
+ return skipToStatementStart(danglingElse, false);
+
+ // Scope introduction: special treat who special is
+ case STPSymbols.TokenLPAREN:
+ case STPSymbols.TokenLBRACE:
+ case STPSymbols.TokenLBRACKET:
+ return handleScopeIntroduction(Math.min(offset + 1, fDocument.getLength()), true);
+
+ case STPSymbols.TokenEOF:
+ // trap when hitting start of document
+ return NOT_FOUND;
+
+ case STPSymbols.TokenEQUAL:
+ // indent assignments
+ fIndent= fPrefs.prefAssignmentIndent;
+ return fPosition;
+
+ case STPSymbols.TokenCOLON:
+ pos= fPosition;
+ if (looksLikeCaseStatement()) {
+ fIndent= fPrefs.prefCaseBlockIndent;
+ return pos;
+ }
+ fPosition= pos;
+ if (looksLikeTypeInheritanceDecl()) {
+ fIndent= fPrefs.prefContinuationIndent;
+ return pos;
+ }
+ fPosition= pos;
+ if (looksLikeConstructorInitializer()) {
+ fIndent= fPrefs.prefBlockIndent;
+ return pos;
+ }
+ fPosition= pos;
+ if (isConditional()) {
+ fPosition= offset;
+ fLine= line;
+ return skipToPreviousListItemOrListStart();
+ }
+ fPosition= pos;
+ return skipToPreviousListItemOrListStart();
+
+ case STPSymbols.TokenQUESTIONMARK:
+ if (fPrefs.prefTernaryDeepAlign) {
+ setFirstElementAlignment(fPosition, offset + 1);
+ } else {
+ fIndent= fPrefs.prefTernaryIndent;
+ }
+ return fPosition;
+
+ // Indentation for blockless introducers:
+ case STPSymbols.TokenDO:
+ case STPSymbols.TokenWHILE:
+ case STPSymbols.TokenELSE:
+ fIndent= fPrefs.prefSimpleIndent;
+ return fPosition;
+
+ case STPSymbols.TokenTRY:
+ return skipToStatementStart(danglingElse, false);
+
+ case STPSymbols.TokenRETURN:
+ case STPSymbols.TokenTYPEDEF:
+ case STPSymbols.TokenUSING:
+ fIndent = fPrefs.prefContinuationIndent;
+ return fPosition;
+
+ case STPSymbols.TokenCONST:
+ nextToken();
+ if (fToken != STPSymbols.TokenRPAREN) {
+ return skipToPreviousListItemOrListStart();
+ }
+ // could be const method decl
+ //$FALL-THROUGH$
+ case STPSymbols.TokenRPAREN:
+ if (skipScope(STPSymbols.TokenLPAREN, STPSymbols.TokenRPAREN)) {
+ int scope= fPosition;
+ nextToken();
+ if (fToken == STPSymbols.TokenIF || fToken == STPSymbols.TokenWHILE || fToken == STPSymbols.TokenFOR) {
+ fIndent= fPrefs.prefSimpleIndent;
+ return fPosition;
+ }
+ if (fToken == STPSymbols.TokenSWITCH) {
+ return fPosition;
+ }
+ fPosition= scope;
+ if (looksLikeMethodDecl()) {
+ return skipToStatementStart(danglingElse, false);
+ }
+ if (fToken == STPSymbols.TokenCATCH) {
+ return skipToStatementStart(danglingElse, false);
+ }
+ fPosition= scope;
+ if (looksLikeAnonymousTypeDecl()) {
+ return skipToStatementStart(danglingElse, false);
+ }
+ }
+ // restore
+ fPosition= offset;
+ fLine= line;
+ // else: fall through to default
+ return skipToPreviousListItemOrListStart();
+
+ case STPSymbols.TokenCOMMA:
+ // Inside a list of some type.
+ // Easy if there is already a list item before with its own indentation - we just align.
+ // If not: take the start of the list (LPAREN, LBRACE, LBRACKET) and either align or
+ // indent by list-indent.
+ return skipToPreviousListItemOrListStart();
+
+ default:
+ // Inside whatever we don't know about:
+ // C would treat this as a list, but in SystemTap we might just have a line that doesn't
+ // end in a semi-colon. We want to indent to the same level as the statement.
+ return skipToStatementStart(danglingElse, false);
+ }
+ }
+
+ /**
+ * Test whether an identifier encountered during scanning is part of
+ * a type declaration, by scanning backward and ignoring any identifiers, commas,
+ * and colons until we hit <code>class</code>, <code>struct</code>, <code>union</code>,
+ * or <code>enum</code>. If any braces, semicolons, or parentheses are encountered,
+ * this is not a type declaration.
+ * @return the reference offset of the start of the statement
+ */
+ private int matchTypeDeclaration() {
+ while (true) {
+ nextToken();
+ if (fToken == STPSymbols.TokenIDENT
+ || fToken == STPSymbols.TokenCOMMA
+ || fToken == STPSymbols.TokenCOLON
+ || fToken == STPSymbols.TokenPUBLIC
+ || fToken == STPSymbols.TokenPROTECTED
+ || fToken == STPSymbols.TokenPRIVATE) {
+ continue;
+ }
+ if (fToken == STPSymbols.TokenCLASS
+ || fToken == STPSymbols.TokenSTRUCT
+ || fToken == STPSymbols.TokenUNION) {
+ // inside a type declaration? Only so if not preceded by '(' or ',' as in
+ // a parameter list. To be safe, only accept ';' or EOF
+ int pos= fPosition;
+ nextToken();
+ if (fToken == STPSymbols.TokenSEMICOLON || fToken == STPSymbols.TokenEOF) {
+ return pos;
+ } else {
+ return NOT_FOUND;
+ }
+ } else {
+ return NOT_FOUND;
+ }
+ }
+ }
+
+ /**
+ * Test whether the colon at the current position marks a case statement
+ *
+ * @return <code>true</code> if this looks like a case statement
+ */
+ private boolean looksLikeCaseStatement() {
+ nextToken();
+ switch (fToken) {
+ case STPSymbols.TokenCASE:
+ // char literal got skipped
+ return true;
+ case STPSymbols.TokenIDENT:
+ nextToken();
+ while (skipQualifiers()) {
+ nextToken();
+ }
+ while (fToken == STPSymbols.TokenMINUS || fToken == STPSymbols.TokenPLUS) {
+ nextToken();
+ }
+ if (fToken == STPSymbols.TokenCASE) {
+ return true;
+ }
+ break;
+ case STPSymbols.TokenOTHER:
+ nextToken();
+ if (fToken == STPSymbols.TokenCASE) {
+ return true;
+ }
+ break;
+ case STPSymbols.TokenDEFAULT:
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Test whether the colon at the current position marks a type inheritance decl.
+ *
+ * @return <code>true</code> if this looks like a type inheritance decl.
+ */
+ private boolean looksLikeTypeInheritanceDecl() {
+ nextToken();
+ switch (fToken) {
+ case STPSymbols.TokenIDENT:
+ nextToken();
+ while (skipQualifiers()) {
+ nextToken();
+ }
+ switch (fToken) {
+ case STPSymbols.TokenCLASS:
+ case STPSymbols.TokenSTRUCT:
+ case STPSymbols.TokenUNION:
+ return true;
+ }
+ break;
+ }
+ return false;
+ }
+
+ /**
+ * Test whether the colon at the current position marks a constructor initializer list.
+ *
+ * @return <code>true</code> if this looks like a constructor initializer list.
+ */
+ private boolean looksLikeConstructorInitializer() {
+ nextToken();
+ if (fToken != STPSymbols.TokenRPAREN) {
+ return false;
+ }
+ if (!skipScope()) {
+ return false;
+ }
+ nextToken();
+ if (fToken == STPSymbols.TokenTHROW) {
+ nextToken();
+ if (fToken != STPSymbols.TokenRPAREN) {
+ return false;
+ }
+ if (!skipScope()) {
+ return false;
+ }
+ nextToken();
+ }
+ if (fToken != STPSymbols.TokenIDENT) {
+ return false;
+ }
+ nextToken();
+ switch (fToken) {
+ case STPSymbols.TokenCOLON:
+ nextToken();
+ switch (fToken) {
+ case STPSymbols.TokenCOLON: // A::A() :
+ case STPSymbols.TokenPUBLIC: // public: A() :
+ case STPSymbols.TokenPROTECTED:
+ case STPSymbols.TokenPRIVATE:
+ return true;
+ }
+ return false;
+
+ case STPSymbols.TokenLBRACE: // class A { A() :
+ case STPSymbols.TokenRBRACE:
+ case STPSymbols.TokenSEMICOLON:
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Test whether the left brace at the current position marks an enum decl.
+ *
+ * @return <code>true</code> if this looks like an enum decl.
+ */
+ private boolean looksLikeEnumDeclaration() {
+ int pos = fPosition;
+ nextToken();
+ if (fToken == STPSymbols.TokenIDENT) {
+ nextToken();
+ while (skipQualifiers()) {
+ nextToken();
+ }
+ }
+ if (fToken == STPSymbols.TokenENUM) {
+ fPosition = pos;
+ return true;
+ }
+ fPosition = pos;
+ return false;
+ }
+
+
+ /**
+ * Test whether the colon at the current position marks an access specifier.
+ *
+ * @return <code>true</code> if current position marks an access specifier
+ */
+ private boolean isAccessSpecifier() {
+ int pos= fPosition;
+ int token = fToken;
+ nextToken();
+ switch (fToken) {
+ case STPSymbols.TokenPUBLIC:
+ case STPSymbols.TokenPROTECTED:
+ case STPSymbols.TokenPRIVATE:
+ return true;
+ }
+ fToken = token;
+ fPosition= pos;
+ return false;
+ }
+
+ /**
+ * Skips to the start of a statement that ends at the current position.
+ *
+ * @param danglingElse whether to indent aligned with the last <code>if</code>
+ * @param isInBlock whether the current position is inside a block, which limits the search scope to
+ * the next scope introducer
+ * @return the reference offset of the start of the statement
+ */
+ private int skipToStatementStart(boolean danglingElse, boolean isInBlock) {
+ final int NOTHING= 0;
+ final int READ_PARENS= 1;
+ final int READ_IDENT= 2;
+ int mayBeMethodBody= NOTHING;
+ boolean isTypeBody= false;
+ int startLine = fLine;
+ while (true) {
+ int prevToken= fToken;
+ nextToken();
+
+ if (isInBlock) {
+ switch (fToken) {
+ // exit on all block introducers
+ case STPSymbols.TokenIF:
+ case STPSymbols.TokenELSE:
+ case STPSymbols.TokenCATCH:
+ case STPSymbols.TokenDO:
+ case STPSymbols.TokenWHILE:
+ case STPSymbols.TokenFOR:
+ case STPSymbols.TokenTRY:
+ fIndent += fPrefs.prefIndentBracesForBlocks ? 1 : 0;
+ return fPosition;
+ case STPSymbols.TokenCLASS:
+ case STPSymbols.TokenSTRUCT:
+ case STPSymbols.TokenUNION:
+ isTypeBody= true;
+ break;
+
+ case STPSymbols.TokenSWITCH:
+ fIndent= fPrefs.prefCaseIndent;
+ return fPosition;
+ }
+ }
+
+ if (fToken == STPSymbols.TokenSEMICOLON && fLine == startLine) {
+ // Skip semicolons on the same line. Otherwise we may never reach beginning of a 'for'
+ // statement.
+ continue;
+ }
+
+ switch (fToken) {
+ // scope introduction through: LPAREN, LBRACE, LBRACKET
+ // search stop on SEMICOLON, RBRACE, COLON, EOF
+ // -> the next token is the start of the statement (i.e. previousPos when backward scanning)
+ case STPSymbols.TokenLPAREN:
+ if (peekToken() == STPSymbols.TokenFOR) {
+ nextToken(); // Consume 'for'
+ fIndent = fPrefs.prefContinuationIndent;
+ return fPosition;
+ }
+ break;
+
+ case STPSymbols.TokenLBRACE:
+ case STPSymbols.TokenSEMICOLON:
+ case STPSymbols.TokenEOF:
+ if (isInBlock)
+ fIndent= getBlockIndent(mayBeMethodBody == READ_IDENT, isTypeBody);
+ return fPreviousPos;
+
+ case STPSymbols.TokenCOLON:
+ switch (prevToken) {
+ case STPSymbols.TokenPRIVATE:
+ case STPSymbols.TokenPROTECTED:
+ case STPSymbols.TokenPUBLIC:
+ continue; // Don't stop at colon in a class declaration
+
+ case STPSymbols.TokenVIRTUAL:
+ switch (peekToken()) {
+ case STPSymbols.TokenPRIVATE:
+ case STPSymbols.TokenPROTECTED:
+ case STPSymbols.TokenPUBLIC:
+ break;
+ default:
+ continue;
+ }
+ }
+ int pos= fPreviousPos;
+ if (!isConditional())
+ return pos;
+ break;
+
+ case STPSymbols.TokenRBRACE:
+ // RBRACE is a little tricky: it can be the end of an array definition, but
+ // usually it is the end of a previous block
+ pos= fPreviousPos; // store state
+ if (skipScope()) {
+ if (looksLikeArrayInitializerIntro()) {
+ continue; // it's an array
+ }
+ if (prevToken == STPSymbols.TokenSEMICOLON) {
+ // end of type def
+ continue;
+ }
+ }
+ if (isInBlock)
+ fIndent= getBlockIndent(mayBeMethodBody == READ_IDENT, isTypeBody);
+ return pos; // it's not - do as with all the above
+
+ // scopes: skip them
+ case STPSymbols.TokenRPAREN:
+ if (isInBlock)
+ mayBeMethodBody= READ_PARENS;
+ // fall thru
+ pos= fPreviousPos;
+ if (skipScope())
+ break;
+ else
+ return pos;
+ case STPSymbols.TokenRBRACKET:
+ pos= fPreviousPos;
+ if (skipScope())
+ break;
+ else
+ return pos;
+
+ // IF / ELSE: align the position after the conditional block with the if
+ // so we are ready for an else, except if danglingElse is false
+ // in order for this to work, we must skip an else to its if
+ case STPSymbols.TokenIF:
+ if (danglingElse)
+ return fPosition;
+ else
+ break;
+ case STPSymbols.TokenELSE:
+ // skip behind the next if, as we have that one covered
+ pos= fPosition;
+ if (skipNextIF())
+ break;
+ else
+ return pos;
+
+ case STPSymbols.TokenDO:
+ // align the WHILE position with its do
+ return fPosition;
+
+ case STPSymbols.TokenWHILE:
+ // this one is tricky: while can be the start of a while loop
+ // or the end of a do - while
+ pos= fPosition;
+ if (hasMatchingDo()) {
+ // continue searching from the DO on
+ break;
+ } else {
+ // continue searching from the WHILE on
+ fPosition= pos;
+ break;
+ }
+ case STPSymbols.TokenIDENT:
+ if (mayBeMethodBody == READ_PARENS)
+ mayBeMethodBody= READ_IDENT;
+ break;
+
+ default:
+ // keep searching
+ }
+ }
+ }
+
+ private int getBlockIndent(boolean isMethodBody, boolean isTypeBody) {
+ if (isTypeBody) {
+ return fPrefs.prefTypeIndent + fPrefs.prefAccessSpecifierIndent;
+ } else if (isMethodBody) {
+ return fPrefs.prefMethodBodyIndent + (fPrefs.prefIndentBracesForMethods ? 1 : 0);
+ } else {
+ return fIndent;
+ }
+ }
+
+ /**
+ * Returns <code>true</code> if the colon at the current position is part of a conditional
+ * (ternary) expression, <code>false</code> otherwise.
+ *
+ * @return <code>true</code> if the colon at the current position is part of a conditional
+ */
+ private boolean isConditional() {
+ while (true) {
+ int previous= fToken;
+ nextToken();
+ switch (fToken) {
+ // search for case labels, which consist of (possibly qualified) identifiers or numbers
+ case STPSymbols.TokenIDENT:
+ if (previous == STPSymbols.TokenIDENT) {
+ return false;
+ }
+ // fall thru
+ continue;
+ case STPSymbols.TokenDOUBLECOLON:
+ case STPSymbols.TokenOTHER:
+ case STPSymbols.TokenMINUS:
+ case STPSymbols.TokenPLUS:
+ continue;
+
+ case STPSymbols.TokenQUESTIONMARK:
+ return true;
+
+ case STPSymbols.TokenSEMICOLON:
+ case STPSymbols.TokenLBRACE:
+ case STPSymbols.TokenRBRACE:
+ case STPSymbols.TokenCASE:
+ case STPSymbols.TokenDEFAULT:
+ case STPSymbols.TokenPUBLIC:
+ case STPSymbols.TokenPROTECTED:
+ case STPSymbols.TokenPRIVATE:
+ case STPSymbols.TokenCLASS:
+ case STPSymbols.TokenSTRUCT:
+ case STPSymbols.TokenUNION:
+ return false;
+
+ default:
+ return true;
+ }
+ }
+ }
+
+ /**
+ * Returns as a reference any previous <code>switch</code> labels (<code>case</code>
+ * or <code>default</code>) or the offset of the brace that scopes the switch
+ * statement. Sets <code>fIndent</code> to <code>prefCaseIndent</code> upon
+ * a match.
+ *
+ * @return the reference offset for a <code>switch</code> label
+ */
+ private int matchCaseAlignment() {
+ while (true) {
+ nextToken();
+ switch (fToken) {
+ // invalid cases: another case label or an LBRACE must come before a case
+ // -> bail out with the current position
+ case STPSymbols.TokenLPAREN:
+ case STPSymbols.TokenLBRACKET:
+ case STPSymbols.TokenEOF:
+ return fPosition;
+
+ case STPSymbols.TokenSWITCH:
+ // start of switch statement
+ fIndent= fPrefs.prefCaseIndent;
+ return fPosition;
+
+ case STPSymbols.TokenCASE:
+ case STPSymbols.TokenDEFAULT:
+ // align with previous label
+ fIndent= 0;
+ return fPosition;
+
+ // scopes: skip them
+ case STPSymbols.TokenRPAREN:
+ case STPSymbols.TokenRBRACKET:
+ case STPSymbols.TokenRBRACE:
+ skipScope();
+ break;
+
+ default:
+ // keep searching
+ continue;
+ }
+ }
+ }
+
+ /**
+ * Returns as a reference any previous access specifiers (<code>public</code>,
+ * <code>protected</code> or <code>default</code>) or the offset of the brace that
+ * scopes the class body.
+ * Sets <code>fIndent</code> to <code>prefAccessSpecifierIndent</code> upon
+ * a match.
+ *
+ * @return the reference offset for an access specifier (public/protected/private)
+ */
+ private int matchAccessSpecifierAlignment() {
+ while (true) {
+ nextToken();
+ switch (fToken) {
+ // invalid cases: another access specifier or an LBRACE must come before an access specifier
+ // -> bail out with the current position
+ case STPSymbols.TokenLPAREN:
+ case STPSymbols.TokenLBRACKET:
+ case STPSymbols.TokenEOF:
+ return fPosition;
+
+ case STPSymbols.TokenLBRACE:
+ // opening brace of class body
+ int pos= fPosition;
+ int typeDeclPos= matchTypeDeclaration();
+ fIndent= fPrefs.prefAccessSpecifierIndent;
+ fExtraSpaces = fPrefs.prefAccessSpecifierExtraSpaces;
+ if (typeDeclPos != NOT_FOUND) {
+ return typeDeclPos;
+ }
+ return pos;
+ case STPSymbols.TokenPUBLIC:
+ case STPSymbols.TokenPROTECTED:
+ case STPSymbols.TokenPRIVATE:
+ // align with previous access specifier
+ fIndent= 0;
+ return fPosition;
+
+ // scopes: skip them
+ case STPSymbols.TokenRPAREN:
+ case STPSymbols.TokenRBRACKET:
+ case STPSymbols.TokenRBRACE:
+ skipScope();
+ break;
+
+ default:
+ // keep searching
+ continue;
+ }
+ }
+ }
+
+ /**
+ * Returns the reference position for a list element. The algorithm
+ * tries to match any previous indentation on the same list. If there is none,
+ * the reference position returned is determined depending on the type of list:
+ * The indentation will either match the list scope introducer (e.g. for
+ * method declarations), so called deep indents, or simply increase the
+ * indentation by a number of standard indents. See also {@link #handleScopeIntroduction(int, boolean)}.
+ * @return the reference position for a list item: either a previous list item
+ * that has its own indentation, or the list introduction start.
+ */
+ private int skipToPreviousListItemOrListStart() {
+ int startLine= fLine;
+ int startPosition= fPosition;
+ int linesSkippedInsideScopes = 0;
+ boolean continuationLineCandidate =
+ fToken == STPSymbols.TokenEQUAL || fToken == STPSymbols.TokenSHIFTLEFT ||
+ fToken == STPSymbols.TokenRPAREN;
+ while (true) {
+ int previous = fToken;
+ nextToken();
+
+ // If any line item comes with its own indentation, adapt to it
+ if (fLine < startLine - linesSkippedInsideScopes) {
+ try {
+ int lineOffset= fDocument.getLineOffset(startLine);
+ int bound= Math.min(fDocument.getLength(), startPosition + 1);
+ if ((fToken == STPSymbols.TokenSEMICOLON || fToken == STPSymbols.TokenRBRACE ||
+ fToken == STPSymbols.TokenLBRACE && !looksLikeArrayInitializerIntro() && !looksLikeEnumDeclaration()) &&
+ continuationLineCandidate) {
+ fIndent = fPrefs.prefContinuationIndent;
+ } else {
+ fAlign= fScanner.findNonWhitespaceForwardInAnyPartition(lineOffset, bound);
+ // If the reference line starts with a colon, skip the colon.
+ if (peekToken(fAlign) == STPSymbols.TokenCOLON) {
+ fAlign= fScanner.findNonWhitespaceForwardInAnyPartition(fAlign + 1, bound);
+ }
+ }
+ } catch (BadLocationException e) {
+ // Ignore and return just the position
+ }
+ return startPosition;
+ }
+
+ int line = fLine;
+ switch (fToken) {
+ // scopes: skip them
+ case STPSymbols.TokenRPAREN:
+ continuationLineCandidate = true;
+ //$FALL-THROUGH$
+ case STPSymbols.TokenRBRACKET:
+ case STPSymbols.TokenRBRACE:
+ skipScope();
+ linesSkippedInsideScopes = line - fLine;
+ break;
+
+ // scope introduction: special treat who special is
+ case STPSymbols.TokenLPAREN:
+ case STPSymbols.TokenLBRACE:
+ case STPSymbols.TokenLBRACKET:
+ return handleScopeIntroduction(startPosition + 1, false);
+
+ case STPSymbols.TokenSEMICOLON:
+ return fPosition;
+
+ case STPSymbols.TokenQUESTIONMARK:
+ if (fPrefs.prefTernaryDeepAlign) {
+ setFirstElementAlignment(fPosition - 1, fPosition + 1);
+ } else {
+ fIndent= fPrefs.prefTernaryIndent;
+ }
+ return fPosition;
+
+ case STPSymbols.TokenEQUAL:
+ case STPSymbols.TokenSHIFTLEFT:
+ continuationLineCandidate = true;
+ break;
+
+ case STPSymbols.TokenRETURN:
+ case STPSymbols.TokenUSING:
+ fIndent = fPrefs.prefContinuationIndent;
+ return fPosition;
+
+ case STPSymbols.TokenTYPEDEF:
+ switch (previous) {
+ case STPSymbols.TokenSTRUCT:
+ case STPSymbols.TokenUNION:
+ case STPSymbols.TokenCLASS:
+ case STPSymbols.TokenENUM:
+ break;
+ default:
+ fIndent = fPrefs.prefContinuationIndent;
+ }
+ return fPosition;
+
+ case STPSymbols.TokenEOF:
+ if (continuationLineCandidate) {
+ fIndent = fPrefs.prefContinuationIndent;
+ }
+ return 0;
+ }
+ }
+ }
+
+ /**
+ * Skips a scope and positions the cursor (<code>fPosition</code>) on the
+ * token that opens the scope. Returns <code>true</code> if a matching peer
+ * could be found, <code>false</code> otherwise. The current token when calling
+ * must be one out of <code>STPSymbols.TokenRPAREN</code>, <code>STPSymbols.TokenRBRACE</code>,
+ * and <code>STPSymbols.TokenRBRACKET</code>.
+ *
+ * @return <code>true</code> if a matching peer was found, <code>false</code> otherwise
+ */
+ private boolean skipScope() {
+ switch (fToken) {
+ case STPSymbols.TokenRPAREN:
+ return skipScope(STPSymbols.TokenLPAREN, STPSymbols.TokenRPAREN);
+ case STPSymbols.TokenRBRACKET:
+ return skipScope(STPSymbols.TokenLBRACKET, STPSymbols.TokenRBRACKET);
+ case STPSymbols.TokenRBRACE:
+ return skipScope(STPSymbols.TokenLBRACE, STPSymbols.TokenRBRACE);
+ case STPSymbols.TokenGREATERTHAN:
+ if (!fPrefs.prefHasTemplates)
+ return false;
+ int storedPosition= fPosition;
+ int storedToken= fToken;
+ nextToken();
+ switch (fToken) {
+ case STPSymbols.TokenIDENT:
+ fPosition = storedPosition;
+ if (skipScope(STPSymbols.TokenLESSTHAN, STPSymbols.TokenGREATERTHAN))
+ return true;
+ break;
+ case STPSymbols.TokenQUESTIONMARK:
+ case STPSymbols.TokenGREATERTHAN:
+ fPosition = storedPosition;
+ if (skipScope(STPSymbols.TokenLESSTHAN, STPSymbols.TokenGREATERTHAN))
+ return true;
+ break;
+ }
+ // <> are harder to detect - restore the position if we fail
+ fPosition= storedPosition;
+ fToken= storedToken;
+ return false;
+
+ default:
+ // programming error
+ Assert.isTrue(false);
+ return false;
+ }
+ }
+
+ /**
+ * Returns the contents of the current token.
+ *
+ * @return the contents of the current token
+ */
+ private CharSequence getTokenContent() {
+ return new DocumentCharacterIterator(fDocument, fPosition, fPreviousPos);
+ }
+
+ /**
+ * Handles the introduction of a new scope. The current token must be one out
+ * of <code>STPSymbols.TokenLPAREN</code>, <code>STPSymbols.TokenLBRACE</code>,
+ * and <code>STPSymbols.TokenLBRACKET</code>. Returns as the reference position
+ * either the token introducing the scope or - if available - the first
+ * token after that.
+ *
+ * <p>Depending on the type of scope introduction, the indentation will align
+ * (deep indenting) with the reference position (<code>fAlign</code> will be
+ * set to the reference position) or <code>fIndent</code> will be set to
+ * the number of indentation units.
+ * </p>
+ *
+ * @param bound the bound for the search for the first token after the scope
+ * introduction.
+ * @param firstToken <code>true</code> if we are dealing with the first token after
+ * the opening parenthesis.
+ * @return the indent
+ */
+ private int handleScopeIntroduction(int bound, boolean firstToken) {
+ int pos= fPosition; // store
+
+ switch (fToken) {
+ // scope introduction: special treat who special is
+ case STPSymbols.TokenLPAREN:
+ // special: method declaration deep indentation
+ if (looksLikeMethodDecl()) {
+ if (firstToken ? fPrefs.prefMethodDeclFirstParameterDeepIndent : fPrefs.prefMethodDeclDeepIndent) {
+ return setFirstElementAlignment(pos, bound);
+ } else {
+ fIndent= fPrefs.prefMethodDeclIndent;
+ return pos;
+ }
+ } else {
+ fPosition= pos;
+ if (looksLikeMethodCall()) {
+ if (firstToken ? fPrefs.prefMethodCallFirstParameterDeepIndent : fPrefs.prefMethodCallDeepIndent) {
+ return setFirstElementAlignment(pos, bound);
+ } else {
+ fIndent= fPrefs.prefMethodCallIndent;
+ return pos;
+ }
+ } else if (fPrefs.prefParenthesisDeepIndent) {
+ return setFirstElementAlignment(pos, bound);
+ }
+ }
+
+ // normal: return the parenthesis as reference
+ fIndent= fPrefs.prefParenthesisIndent;
+ return pos;
+
+ case STPSymbols.TokenLBRACE:
+ final boolean looksLikeArrayInitializerIntro= looksLikeArrayInitializerIntro();
+ // special: array initializer
+ if (looksLikeArrayInitializerIntro) {
+ if (fPrefs.prefArrayDeepIndent)
+ return setFirstElementAlignment(pos, bound);
+ else
+ fIndent= fPrefs.prefArrayIndent;
+ } else if (isNamespace() || isLinkageSpec()) {
+ fIndent= fPrefs.prefNamespaceBodyIndent;
+ } else if (looksLikeEnumDeclaration()) {
+ fIndent = fPrefs.prefTypeIndent;
+ } else {
+ int typeDeclPos = matchTypeDeclaration();
+ if (typeDeclPos == NOT_FOUND) {
+ fIndent= fPrefs.prefBlockIndent;
+ } else {
+ fIndent= fPrefs.prefAccessSpecifierIndent + fPrefs.prefTypeIndent;
+ }
+ }
+
+ // normal: skip to the statement start before the scope introducer
+ // opening braces are often on differently ending indents than e.g. a method definition
+ if (!looksLikeArrayInitializerIntro) {
+ fPosition= pos; // restore
+ return skipToStatementStart(true, true); // set to true to match the first if
+ } else {
+ return pos;
+ }
+
+ case STPSymbols.TokenLBRACKET:
+ // special: method declaration deep indentation
+ if (fPrefs.prefArrayDimensionsDeepIndent) {
+ return setFirstElementAlignment(pos, bound);
+ }
+
+ // normal: return the bracket as reference
+ fIndent= fPrefs.prefBracketIndent;
+ return pos; // restore
+
+ default:
+ // programming error
+ Assert.isTrue(false);
+ return -1; // dummy
+ }
+ }
+
+ /**
+ * Sets the deep indent offset (<code>fAlign</code>) to either the offset
+ * right after <code>scopeIntroducerOffset</code> or - if available - the
+ * first C token after <code>scopeIntroducerOffset</code>, but before
+ * <code>bound</code>.
+ *
+ * @param scopeIntroducerOffset the offset of the scope introducer
+ * @param bound the bound for the search for another element
+ * @return the reference position
+ */
+ private int setFirstElementAlignment(int scopeIntroducerOffset, int bound) {
+ int firstPossible= scopeIntroducerOffset + 1; // align with the first position after the scope intro
+ fAlign= fScanner.findNonWhitespaceForwardInAnyPartition(firstPossible, bound);
+ if (fAlign == NOT_FOUND) {
+ fAlign= firstPossible;
+ } else {
+ try {
+ IRegion lineRegion = fDocument.getLineInformationOfOffset(scopeIntroducerOffset);
+ if (fAlign > lineRegion.getOffset() + lineRegion.getLength()) {
+ fAlign= firstPossible;
+ }
+ } catch (BadLocationException e) {
+ // Ignore.
+ }
+ }
+ return fAlign;
+ }
+
+ /**
+ * Returns <code>true</code> if the next token received after calling
+ * <code>nextToken</code> is either an equal sign, an opening brace,
+ * a comma or an array designator ('[]').
+ *
+ * @return <code>true</code> if the next elements look like the start of an array definition
+ */
+ private boolean looksLikeArrayInitializerIntro() {
+ int pos= fPosition;
+ nextToken();
+ switch (fToken) {
+ case STPSymbols.TokenEQUAL:
+ return true;
+ case STPSymbols.TokenRBRACKET:
+ return skipBrackets();
+ case STPSymbols.TokenLBRACE:
+ if (looksLikeArrayInitializerIntro()) {
+ fPosition= pos;
+ return true;
+ }
+ return false;
+ case STPSymbols.TokenCOMMA:
+ fPosition= pos;
+ return true;
+ }
+ fPosition= pos;
+ return false;
+ }
+
+ /**
+ * Returns <code>true</code> if the the current token is "namespace", or the current token
+ * is an identifier and the previous token is "namespace".
+ *
+ * @return <code>true</code> if the next elements look like the start of a namespace declaration.
+ */
+ private boolean isNamespace() {
+ int pos = fPosition;
+ nextToken();
+ if (fToken == STPSymbols.TokenNAMESPACE) {
+ fPosition = pos;
+ return true; // Anonymous namespace
+ } else if (fToken == STPSymbols.TokenIDENT) {
+ nextToken(); // Get previous token
+ if (fToken == STPSymbols.TokenNAMESPACE) {
+ fPosition = pos;
+ return true; // Named namespace
+ }
+ }
+ fPosition = pos;
+ return false;
+ }
+
+ /**
+ * Returns <code>true</code> if the current token is keyword "extern".
+ *
+ * @return <code>true</code> if the next elements look like the start of a linkage spec.
+ */
+ private boolean isLinkageSpec() {
+ int pos = fPosition;
+ nextToken();
+ if (fToken == STPSymbols.TokenEXTERN) {
+ fPosition = pos;
+ return true;
+ }
+ fPosition = pos;
+ return false;
+ }
+
+ /**
+ * Skips over the next <code>if</code> keyword. The current token when calling
+ * this method must be an <code>else</code> keyword. Returns <code>true</code>
+ * if a matching <code>if</code> could be found, <code>false</code> otherwise.
+ * The cursor (<code>fPosition</code>) is set to the offset of the <code>if</code>
+ * token.
+ *
+ * @return <code>true</code> if a matching <code>if</code> token was found, <code>false</code> otherwise
+ */
+ private boolean skipNextIF() {
+ Assert.isTrue(fToken == STPSymbols.TokenELSE);
+
+ while (true) {
+ nextToken();
+ switch (fToken) {
+ // scopes: skip them
+ case STPSymbols.TokenRPAREN:
+ case STPSymbols.TokenRBRACKET:
+ case STPSymbols.TokenRBRACE:
+ skipScope();
+ break;
+
+ case STPSymbols.TokenIF:
+ // found it, return
+ return true;
+ case STPSymbols.TokenELSE:
+ // recursively skip else-if blocks
+ skipNextIF();
+ break;
+
+ // shortcut scope starts
+ case STPSymbols.TokenLPAREN:
+ case STPSymbols.TokenLBRACE:
+ case STPSymbols.TokenLBRACKET:
+ case STPSymbols.TokenEOF:
+ return false;
+ }
+ }
+ }
+
+ /**
+ * while(condition); is ambiguous when parsed backwardly, as it is a valid
+ * statement by its own, so we have to check whether there is a matching
+ * do. A <code>do</code> can either be separated from the while by a
+ * block, or by a single statement, which limits our search distance.
+ *
+ * @return <code>true</code> if the <code>while</code> currently in
+ * <code>fToken</code> has a matching <code>do</code>.
+ */
+ private boolean hasMatchingDo() {
+ Assert.isTrue(fToken == STPSymbols.TokenWHILE);
+ nextToken();
+ switch (fToken) {
+ case STPSymbols.TokenRBRACE:
+ skipScope(); // and fall thru
+ skipToStatementStart(false, false);
+ return fToken == STPSymbols.TokenDO;
+
+ case STPSymbols.TokenSEMICOLON:
+ skipToStatementStart(false, false);
+ return fToken == STPSymbols.TokenDO;
+ }
+ return false;
+ }
+
+ /**
+ * Skips pointer operators if the current token is a pointer operator.
+ *
+ * @return <code>true</code> if a <code>*</code> or <code>&amp;</code> could be scanned, the
+ * current token is left at the operator.
+ */
+ private boolean skipPointerOperators() {
+ if (fToken == STPSymbols.TokenOTHER) {
+ CharSequence token= getTokenContent().toString().trim();
+ if (token.length() == 1 && token.charAt(0) == '*' || token.charAt(0) == '&') {
+ return true;
+ }
+ } else if (fToken == STPSymbols.TokenCONST) {
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Skips brackets if the current token is a RBRACKET. There can be nothing
+ * but whitespace in between, this is only to be used for <code>[]</code> elements.
+ *
+ * @return <code>true</code> if a <code>[]</code> could be scanned, the
+ * current token is left at the LBRACKET.
+ */
+ private boolean skipBrackets() {
+ if (fToken == STPSymbols.TokenRBRACKET) {
+ nextToken();
+ if (fToken == STPSymbols.TokenLBRACKET) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Skips scope qualifiers of identifiers.
+ *
+ * @return <code>true</code> if a qualifier was encountered, the last token
+ * will be an IDENT.
+ */
+ private boolean skipQualifiers() {
+ if (fToken == STPSymbols.TokenDOUBLECOLON) {
+ nextToken();
+ if (fToken == STPSymbols.TokenIDENT) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Reads the next token in backward direction from the heuristic scanner
+ * and sets the fields <code>fToken, fPreviousPosition</code> and <code>fPosition</code>
+ * accordingly.
+ */
+ private void nextToken() {
+ nextToken(fPosition);
+ }
+
+ /**
+ * Reads the next token in backward direction of <code>start</code> from
+ * the heuristic scanner and sets the fields <code>fToken, fPreviousPosition</code>
+ * and <code>fPosition</code> accordingly.
+ *
+ * @param start the start offset from which to scan backwards
+ */
+ private void nextToken(int start) {
+ fToken= fScanner.previousToken(start - 1, STPHeuristicScanner.UNBOUND);
+ fPreviousPos= start;
+ fPosition= fScanner.getPosition() + 1;
+ try {
+ fLine= fDocument.getLineOfOffset(fPosition);
+ } catch (BadLocationException e) {
+ fLine= -1;
+ }
+ }
+
+ /**
+ * Reads the next token in backward direction from the heuristic scanner
+ * and returns that token without changing the current position.
+ */
+ private int peekToken() {
+ return fScanner.previousToken(fPosition - 1, STPHeuristicScanner.UNBOUND);
+ }
+
+ /**
+ * Returns <code>true</code> if the current tokens look like a method
+ * declaration header (i.e. only the return type and method name). The
+ * heuristic calls <code>nextToken</code> and expects an identifier
+ * (method name) and an optional return type declaration.
+ *
+ * @return <code>true</code> if the current position looks like a method
+ * declaration header.
+ */
+ private boolean looksLikeMethodDecl() {
+ nextToken();
+ switch (fToken) {
+ case STPSymbols.TokenIDENT: // method name
+ int pos= fPosition;
+ nextToken();
+ // check destructor tilde
+ if (fToken == STPSymbols.TokenTILDE) {
+ return true;
+ }
+ if (skipQualifiers()) {
+ return true;
+ }
+ // optional brackets for array valued return types
+ while (skipBrackets()) {
+ nextToken();
+ }
+ while (skipPointerOperators()) {
+ nextToken();
+ }
+ switch (fToken) {
+ case STPSymbols.TokenIDENT:
+ return true;
+ case STPSymbols.TokenSEMICOLON:
+ case STPSymbols.TokenRBRACE:
+ fPosition= pos;
+ return true;
+ case STPSymbols.TokenLBRACE:
+ if (fScanner.looksLikeCompositeTypeDefinitionBackward(fPosition, STPHeuristicScanner.UNBOUND)) {
+ fPosition= pos;
+ return true;
+ }
+ break;
+ case STPSymbols.TokenCOMMA:
+ nextToken();
+ if (fToken == STPSymbols.TokenRPAREN) {
+ // field initializer
+ if (skipScope()) {
+ return looksLikeMethodDecl();
+ }
+ }
+ break;
+ case STPSymbols.TokenCOLON:
+ nextToken();
+ switch (fToken) {
+ case STPSymbols.TokenPUBLIC:
+ case STPSymbols.TokenPROTECTED:
+ case STPSymbols.TokenPRIVATE:
+ fPosition= pos;
+ return true;
+ case STPSymbols.TokenRPAREN:
+ // constructor initializer
+ if (skipScope()) {
+ pos = fPosition;
+ nextToken();
+ // optional throw
+ if (fToken == STPSymbols.TokenTHROW) {
+ nextToken();
+ if (fToken != STPSymbols.TokenRPAREN || !skipScope()) {
+ return false;
+ }
+ } else {
+ fPosition = pos;
+ }
+ return looksLikeMethodDecl();
+ }
+ break;
+ }
+ }
+ break;
+ case STPSymbols.TokenARROW:
+ case STPSymbols.TokenCOMMA:
+ case STPSymbols.TokenEQUAL:
+ case STPSymbols.TokenGREATERTHAN:
+ case STPSymbols.TokenLESSTHAN:
+ case STPSymbols.TokenMINUS:
+ case STPSymbols.TokenPLUS:
+ case STPSymbols.TokenSHIFTRIGHT:
+ case STPSymbols.TokenSHIFTLEFT:
+ case STPSymbols.TokenDELETE:
+ case STPSymbols.TokenNEW:
+ nextToken();
+ return fToken == STPSymbols.TokenOPERATOR;
+ case STPSymbols.TokenRPAREN:
+ nextToken();
+ if (fToken != STPSymbols.TokenLPAREN)
+ return false;
+ nextToken();
+ return fToken == STPSymbols.TokenOPERATOR;
+ case STPSymbols.TokenRBRACKET:
+ nextToken();
+ if (fToken != STPSymbols.TokenLBRACKET)
+ return false;
+ nextToken();
+ if (fToken == STPSymbols.TokenNEW || fToken == STPSymbols.TokenDELETE)
+ nextToken();
+ return fToken == STPSymbols.TokenOPERATOR;
+ case STPSymbols.TokenOTHER:
+ if (getTokenContent().length() == 1) {
+ nextToken();
+ if (fToken == STPSymbols.TokenOPERATOR)
+ return true;
+ }
+ if (getTokenContent().length() == 1) {
+ nextToken();
+ if (fToken == STPSymbols.TokenOPERATOR)
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Returns <code>true</code> if the current tokens look like an anonymous type declaration
+ * header (i.e. a type name (potentially qualified) and a new keyword). The heuristic calls
+ * <code>nextToken</code> and expects a possibly qualified identifier (type name) and a new
+ * keyword
+ *
+ * @return <code>true</code> if the current position looks like a anonymous type declaration
+ * header.
+ */
+ private boolean looksLikeAnonymousTypeDecl() {
+ nextToken();
+ if (fToken == STPSymbols.TokenIDENT) { // type name
+ nextToken();
+ while (fToken == STPSymbols.TokenOTHER) { // dot of qualification
+ nextToken();
+ if (fToken != STPSymbols.TokenIDENT) // qualifying name
+ return false;
+ nextToken();
+ }
+ return fToken == STPSymbols.TokenNEW;
+ }
+ return false;
+ }
+
+ /**
+ * Returns <code>true</code> if the current tokens look like beginning of a method
+ * call (i.e. an identifier as opposed to a keyword taking parenthesized parameters
+ * such as <code>if</code>).
+ * <p>The heuristic calls <code>nextToken</code> and expects an identifier
+ * (method name).
+ *
+ * @return <code>true</code> if the current position looks like a method call
+ * header.
+ */
+ private boolean looksLikeMethodCall() {
+ nextToken();
+ if (fToken == STPSymbols.TokenGREATERTHAN) {
+ if (!skipScope())
+ return false;
+ nextToken();
+ }
+ return fToken == STPSymbols.TokenIDENT; // method name
+ }
+
+ /**
+ * Scans tokens for the matching opening peer. The internal cursor
+ * (<code>fPosition</code>) is set to the offset of the opening peer if found.
+ *
+ * @param openToken the opening peer token
+ * @param closeToken the closing peer token
+ * @return <code>true</code> if a matching token was found, <code>false</code>
+ * otherwise
+ */
+ private boolean skipScope(int openToken, int closeToken) {
+ int depth= 1;
+
+ while (true) {
+ nextToken();
+
+ if (fToken == closeToken) {
+ depth++;
+ } else if (fToken == openToken) {
+ depth--;
+ if (depth == 0)
+ return true;
+ } else if (fToken == STPSymbols.TokenEOF) {
+ return false;
+ }
+ }
+ }
+}
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPLocation.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPLocation.java
new file mode 100644
index 0000000000..bec8353066
--- /dev/null
+++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPLocation.java
@@ -0,0 +1,57 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ * Anton Leherbauer (Wind River Systems)
+ * Red Hat Inc. - modified for use in SystemTap
+ *******************************************************************************/
+package org.eclipse.linuxtools.internal.systemtap.ui.ide.editors.stp;
+
+/**
+ * A location maintains positional information both in original source
+ * and in the output source.
+ * It remembers source offsets, line/column and indentation level.
+ *
+ * @since 4.0
+ */
+public class STPLocation {
+ public int inputOffset;
+ public int outputLine;
+ public int outputColumn;
+ public int outputIndentationLevel;
+ public boolean needSpace;
+ public boolean pendingSpace;
+ public int numberOfIndentations;
+
+ // chunk management
+ public int lastNumberOfNewLines;
+
+ // edits management
+ int editsIndex;
+ OptimizedReplaceEdit textEdit;
+
+ public Runnable tailFormatter;
+
+ public STPLocation(STPScribe scribe, int sourceRestart){
+ update(scribe, sourceRestart);
+ }
+
+ public void update(STPScribe scribe, int sourceRestart){
+ this.inputOffset = sourceRestart;
+ this.outputLine = scribe.line;
+ this.outputColumn = scribe.column;
+ this.outputIndentationLevel = scribe.indentationLevel;
+ this.needSpace = scribe.needSpace;
+ this.pendingSpace = scribe.pendingSpace;
+ this.numberOfIndentations = scribe.numberOfIndentations;
+ this.lastNumberOfNewLines = scribe.lastNumberOfNewLines;
+ this.editsIndex = scribe.editsIndex;
+ this.textEdit = scribe.getLastEdit();
+ this.tailFormatter = scribe.getTailFormatter();
+ }
+}
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPPartitionScanner.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPPartitionScanner.java
index 1a3dbe1d66..8138f67edc 100644
--- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPPartitionScanner.java
+++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPPartitionScanner.java
@@ -19,19 +19,17 @@ import org.eclipse.jface.text.rules.IToken;
import org.eclipse.jface.text.rules.IWordDetector;
import org.eclipse.jface.text.rules.MultiLineRule;
import org.eclipse.jface.text.rules.RuleBasedPartitionScanner;
-import org.eclipse.jface.text.rules.SingleLineRule;
import org.eclipse.jface.text.rules.Token;
import org.eclipse.jface.text.rules.WordRule;
public class STPPartitionScanner extends RuleBasedPartitionScanner {
+ public final static String STP_PARTITIONING = "__stp_partitioning"; //$NON-NLS-1$
+
public final static String STP_COMMENT = "__stp_comment"; //$NON-NLS-1$
- public final static String STP_KEYWORD = "__stp_keyword"; //$NON-NLS-1$
- public final static String STP_STRING = "__stp_string"; //$NON-NLS-1$
public final static String STP_CONDITIONAL = "__stp_conditional"; //$NON-NLS-1$
- public final static String STP_PROBE = "__stp_probe"; //$NON-NLS-1$
public static String[] STP_PARTITION_TYPES = { IDocument.DEFAULT_CONTENT_TYPE,
- STP_COMMENT, STP_KEYWORD, STP_STRING, STP_CONDITIONAL, STP_PROBE};
+ STP_COMMENT, STP_CONDITIONAL};
/**
* Detect empty comments
@@ -75,26 +73,20 @@ public class STPPartitionScanner extends RuleBasedPartitionScanner {
public STPPartitionScanner() {
IToken stpComment = new Token(STP_COMMENT);
- IToken stpString = new Token(STP_STRING);
IToken stpConditional = new Token(STP_CONDITIONAL);
- IToken stpProbe = new Token(STP_PROBE);
// Add special case word rule.
EmptyCommentRule emptyCommentRule= new EmptyCommentRule(stpComment);
setPredicateRules(new IPredicateRule[] {
new EndOfLineRule("//", stpComment), //$NON-NLS-1$
- new MultiLineRule("probe", "}", stpProbe), //$NON-NLS-1$//$NON-NLS-2$
new MultiLineRule("/*", "*/", stpComment), //$NON-NLS-1$//$NON-NLS-2$
- new EndOfLineRule("/*", stpComment), //$NON-NLS-1$
new EndOfLineRule("#", stpComment), //$NON-NLS-1$
emptyCommentRule,
new EndOfLineRule("#if", stpConditional), //$NON-NLS-1$
new EndOfLineRule("#else", stpConditional), //$NON-NLS-1$
new EndOfLineRule("#endif", stpConditional), //$NON-NLS-1$
new EndOfLineRule("#define", stpConditional), //$NON-NLS-1$
- new SingleLineRule("\"", "\"", stpString, '\\'), //$NON-NLS-1$ //$NON-NLS-2$
- new SingleLineRule("'", "'", stpString, '\\'), //$NON-NLS-1$ //$NON-NLS-2$
});
}
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPProbeScanner.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPProbeScanner.java
new file mode 100644
index 0000000000..2a6b7a45e2
--- /dev/null
+++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPProbeScanner.java
@@ -0,0 +1,56 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2013 Phil Muldoon <pkmuldoon@picobot.org>.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Phil Muldoon <pkmuldoon@picobot.org> - initial API and implementation.
+ * Red Hat Inc. - modification for use in probe scanning
+ *******************************************************************************/
+package org.eclipse.linuxtools.internal.systemtap.ui.ide.editors.stp;
+
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.rules.EndOfLineRule;
+import org.eclipse.jface.text.rules.IPredicateRule;
+import org.eclipse.jface.text.rules.IToken;
+import org.eclipse.jface.text.rules.MultiLineRule;
+import org.eclipse.jface.text.rules.RuleBasedPartitionScanner;
+import org.eclipse.jface.text.rules.SingleLineRule;
+import org.eclipse.jface.text.rules.Token;
+
+public class STPProbeScanner extends RuleBasedPartitionScanner {
+ public final static String STP_STRING = "__stp_string"; //$NON-NLS-1$
+ public final static String STP_PROBE = "__stp_probe"; //$NON-NLS-1$
+ public final static String STP_CONDITIONAL = "__stp_conditional"; //$NON-NLS-1$
+ public final static String STP_COMMENT = "__stp_comment"; //$NON-NLS-1$
+
+ public final static String STP_PROBE_PARTITIONING = "__stp_probe_partitioning"; //$NON-NLS-1$
+
+ public static String[] STP_PROBE_PARTITION_TYPES = { IDocument.DEFAULT_CONTENT_TYPE,
+ STP_COMMENT, STP_STRING, STP_PROBE, STP_CONDITIONAL};
+
+ public STPProbeScanner() {
+
+ IToken stpString = new Token(STP_STRING);
+ IToken stpProbe = new Token(STP_PROBE);
+ IToken stpComment = new Token(STP_COMMENT);
+ IToken stpConditional = new Token(STP_CONDITIONAL);
+
+ setPredicateRules(new IPredicateRule[] {
+ new EndOfLineRule("//", stpComment), //$NON-NLS-1$
+ new MultiLineRule("/*", "*/", stpComment), //$NON-NLS-1$//$NON-NLS-2$
+ new EndOfLineRule("#", stpComment), //$NON-NLS-1$
+ new EndOfLineRule("#if", stpConditional), //$NON-NLS-1$
+ new EndOfLineRule("#else", stpConditional), //$NON-NLS-1$
+ new EndOfLineRule("#endif", stpConditional), //$NON-NLS-1$
+ new EndOfLineRule("#define", stpConditional), //$NON-NLS-1$
+ new SingleLineRule("\"", "\"", stpString, '\\'), //$NON-NLS-1$ //$NON-NLS-2$
+ new SingleLineRule("'", "'", stpString, '\\'), //$NON-NLS-1$ //$NON-NLS-2$
+ new MultiLineRule("probe", "}", stpProbe), //$NON-NLS-1$ //$NON-NLS-2$
+ });
+
+ }
+}
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPScribe.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPScribe.java
new file mode 100644
index 0000000000..992c7cba76
--- /dev/null
+++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPScribe.java
@@ -0,0 +1,2151 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2011, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ * Anton Leherbauer (Wind River Systems)
+ * Sergey Prigogin (Google)
+ * Red Hat Inc. - modified for use in SystemTap
+ *******************************************************************************/
+package org.eclipse.linuxtools.internal.systemtap.ui.ide.editors.stp;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.jface.text.Position;
+import org.eclipse.text.edits.MultiTextEdit;
+import org.eclipse.text.edits.ReplaceEdit;
+import org.eclipse.text.edits.TextEdit;
+
+/**
+ * This class is responsible for dumping formatted source.
+ *
+ * @since 4.0
+ */
+public class STPScribe {
+ private static final String EMPTY_STRING= ""; //$NON-NLS-1$
+ private static final String SPACE= " "; //$NON-NLS-1$
+
+ private static final int INITIAL_SIZE= 100;
+
+ private final STPDefaultCodeFormatterOptions preferences;
+ public final Scanner scanner;
+
+ /** one-based column */
+ public int column= 1;
+
+ // Most specific alignment.
+ public STPAlignment currentAlignment;
+ public STPAlignment memberAlignment;
+ public AlignmentException currentAlignmentException;
+
+ /** @see Alignment#tailFormatter */
+ private Runnable tailFormatter;
+
+ public Token currentToken;
+
+ // Edits management
+ private OptimizedReplaceEdit[] edits;
+ public int editsIndex;
+
+ public int indentationLevel;
+ public int numberOfIndentations;
+ public int indentationSize;
+
+ private final String lineSeparator;
+ private final boolean indentEmptyLines;
+ private final int pageWidth;
+ private boolean preserveNewLines;
+ private boolean checkLineWrapping;
+ public int lastNumberOfNewLines;
+ private boolean preserveLineBreakIndentation;
+ boolean formatBrace;
+ public int line;
+
+ public boolean needSpace;
+ public boolean pendingSpace;
+
+ public int tabLength;
+ public int tabChar;
+ private final boolean useTabsOnlyForLeadingIndents;
+
+ private int textRegionEnd;
+ private int textRegionStart;
+ public int scannerEndPosition;
+
+ private List<Position> fSkipPositions= Collections.emptyList();
+
+ private boolean skipOverInactive;
+
+ private int fSkipStartOffset= Integer.MAX_VALUE;
+ private int fSkipEndOffset;
+ private int fSkippedIndentations;
+
+ /* Comments formatting */
+ private static final int NO_TRAILING_COMMENT = 0x0000;
+ private static final int BASIC_TRAILING_COMMENT = 0x0100;
+ private int[] lineOffsets;
+ private int numLines;
+
+ // Class to store previous line comment information
+ static class LineComment {
+ boolean contiguous;
+ int currentIndentation;
+ int indentation;
+ int lines;
+ char[] leadingSpaces = CharArrayUtils.EMPTY_CHAR_ARRAY;
+ }
+ final LineComment lastLineComment = new LineComment();
+
+ STPScribe(int offset, int length) {
+ scanner= new Scanner();
+ preferences= new STPDefaultCodeFormatterOptions(null);
+ pageWidth= preferences.page_width;
+ tabLength= preferences.tab_size;
+ indentationLevel= 0; // initialize properly
+ numberOfIndentations= 0;
+ useTabsOnlyForLeadingIndents= preferences.use_tabs_only_for_leading_indentations;
+ indentEmptyLines= preferences.indent_empty_lines;
+ tabChar= preferences.tab_char;
+ if (tabChar == STPDefaultCodeFormatterOptions.MIXED) {
+ indentationSize= preferences.indentation_size;
+ } else {
+ indentationSize= tabLength;
+ }
+ lineSeparator= preferences.line_separator;
+ indentationLevel= preferences.initial_indentation_level * indentationSize;
+ preserveNewLines = false;
+ textRegionStart= offset;
+ textRegionEnd= offset + length;
+ reset();
+ }
+
+ private final void addDeleteEdit(int start, int end) {
+ addOptimizedReplaceEdit(start, end - start + 1, EMPTY_STRING);
+ }
+
+ public final void addInsertEdit(int insertPosition, CharSequence insertedString) {
+ addOptimizedReplaceEdit(insertPosition, 0, insertedString);
+ }
+
+ /**
+ * Adds a replace edit.
+ * @param start start offset (inclusive)
+ * @param end end offset (inclusive)
+ * @param replacement the replacement string
+ */
+ public final void addReplaceEdit(int start, int end, CharSequence replacement) {
+ addOptimizedReplaceEdit(start, end - start + 1, replacement);
+ }
+
+ private final void addOptimizedReplaceEdit(int offset, int length, CharSequence replacement) {
+ if (edits.length == editsIndex) {
+ resize();
+ }
+ if (editsIndex > 0) {
+ // Try to merge last two edits
+ final OptimizedReplaceEdit previous= edits[editsIndex - 1];
+ final int previousOffset= previous.offset;
+ final int previousLength= previous.length;
+ final int endOffsetOfPreviousEdit= previousOffset + previousLength;
+ final int replacementLength= replacement.length();
+ final String previousReplacement= previous.replacement;
+ final int previousReplacementLength= previousReplacement.length();
+ if (previousOffset == offset && previousLength == length
+ && (replacementLength == 0 || previousReplacementLength == 0)) {
+ if (currentAlignment != null) {
+ final STPLocation location= currentAlignment.location;
+ if (location.editsIndex == editsIndex) {
+ location.editsIndex--;
+ location.textEdit= previous;
+ }
+ }
+ editsIndex--;
+ return;
+ }
+ if (endOffsetOfPreviousEdit == offset) {
+ if (length != 0) {
+ if (replacementLength != 0) {
+ editsIndex--;
+ appendOptimizedReplaceEdit(previousOffset, previousLength + length,
+ previousReplacement + replacement);
+ } else if (previousLength + length == previousReplacementLength) {
+ // Check the characters. If they are identical,
+ // we can get rid of the previous edit.
+ boolean canBeRemoved= true;
+ loop: for (int i= previousOffset; i < previousOffset + previousReplacementLength; i++) {
+ if (scanner.source[i] != previousReplacement.charAt(i - previousOffset)) {
+ editsIndex--;
+ appendOptimizedReplaceEdit(previousOffset, previousReplacementLength,
+ previousReplacement);
+ canBeRemoved= false;
+ break loop;
+ }
+ }
+ if (canBeRemoved) {
+ if (currentAlignment != null) {
+ final STPLocation location= currentAlignment.location;
+ if (location.editsIndex == editsIndex) {
+ location.editsIndex--;
+ location.textEdit= previous;
+ }
+ }
+ editsIndex--;
+ }
+ } else {
+ editsIndex--;
+ appendOptimizedReplaceEdit(previousOffset, previousLength + length,
+ previousReplacement);
+ }
+ } else {
+ if (replacementLength != 0) {
+ editsIndex--;
+ appendOptimizedReplaceEdit(previousOffset, previousLength,
+ previousReplacement + replacement);
+ }
+ }
+ } else {
+ assert endOffsetOfPreviousEdit < offset;
+ appendOptimizedReplaceEdit(offset, length, replacement);
+ }
+ } else {
+ appendOptimizedReplaceEdit(offset, length, replacement);
+ }
+ }
+
+ /**
+ * Trims redundant prefix from a replacement edit and, if there is anything left, appends
+ * the replacement edit to the edits array.
+ */
+ private void appendOptimizedReplaceEdit(int offset, int length, CharSequence replacement) {
+ int replacementLength = replacement.length();
+ int i;
+ for (i = 0; i < length && i < replacementLength; i++, offset++) {
+ if (scanner.source[offset] != replacement.charAt(i))
+ break;
+ }
+ length -= i;
+ if (i > 0) {
+ replacement = i == replacementLength ?
+ EMPTY_STRING : replacement.subSequence(i, replacementLength);
+ }
+ if (length > 0 || replacement.length() > 0) {
+ edits[editsIndex++]= new OptimizedReplaceEdit(offset, length, replacement);
+ }
+ }
+
+ public void alignFragment(STPAlignment alignment, int fragmentIndex) {
+ alignment.alignFragment(fragmentIndex);
+ }
+
+ public void consumeNextToken() {
+ printComment();
+ currentToken= scanner.nextToken();
+ addDeleteEdit(scanner.getCurrentTokenStartPosition(), scanner.getCurrentTokenEndPosition());
+ }
+
+ public STPAlignment createAlignment(String name, int mode, int count, int sourceRestart) {
+ return createAlignment(name, mode, STPAlignment.R_INNERMOST, count, sourceRestart);
+ }
+
+ public STPAlignment createAlignment(String name, int mode, int count, int sourceRestart,
+ boolean adjust) {
+ return createAlignment(name, mode, STPAlignment.R_INNERMOST, count, sourceRestart, adjust);
+ }
+
+ public STPAlignment createAlignment(String name, int mode, int tieBreakRule, int count,
+ int sourceRestart) {
+ return createAlignment(name, mode, tieBreakRule, count, sourceRestart,
+ preferences.continuation_indentation, false);
+ }
+
+ public STPAlignment createAlignment(String name, int mode, int count, int sourceRestart,
+ int continuationIndent, boolean adjust) {
+ return createAlignment(name, mode, STPAlignment.R_INNERMOST, count, sourceRestart,
+ continuationIndent, adjust);
+ }
+
+ public STPAlignment createAlignment(String name, int mode, int tieBreakRule, int count,
+ int sourceRestart, int continuationIndent, boolean adjust) {
+ STPAlignment alignment= new STPAlignment(name, mode, tieBreakRule, this, count, sourceRestart,
+ continuationIndent);
+ // adjust break indentation
+ if (adjust && memberAlignment != null) {
+ STPAlignment current= memberAlignment;
+ while (current.enclosing != null) {
+ current= current.enclosing;
+ }
+ if ((current.mode & STPAlignment.M_MULTICOLUMN) != 0) {
+ final int indentSize= indentationSize;
+ switch (current.chunkKind) {
+ case STPAlignment.CHUNK_METHOD:
+ case STPAlignment.CHUNK_TYPE:
+ if ((mode & STPAlignment.M_INDENT_BY_ONE) != 0) {
+ alignment.breakIndentationLevel= indentationLevel + indentSize;
+ } else {
+ alignment.breakIndentationLevel= indentationLevel +
+ continuationIndent * indentSize;
+ }
+ alignment.update();
+ break;
+ case STPAlignment.CHUNK_FIELD:
+ if ((mode & STPAlignment.M_INDENT_BY_ONE) != 0) {
+ alignment.breakIndentationLevel= current.originalIndentationLevel + indentSize;
+ } else {
+ alignment.breakIndentationLevel= current.originalIndentationLevel +
+ continuationIndent * indentSize;
+ }
+ alignment.update();
+ break;
+ }
+ } else {
+ switch (current.mode & STPAlignment.SPLIT_MASK) {
+ case STPAlignment.M_COMPACT_SPLIT:
+ case STPAlignment.M_COMPACT_FIRST_BREAK_SPLIT:
+ case STPAlignment.M_NEXT_PER_LINE_SPLIT:
+ case STPAlignment.M_NEXT_SHIFTED_SPLIT:
+ case STPAlignment.M_ONE_PER_LINE_SPLIT:
+ final int indentSize= indentationSize;
+ switch (current.chunkKind) {
+ case STPAlignment.CHUNK_METHOD:
+ case STPAlignment.CHUNK_TYPE:
+ if ((mode & STPAlignment.M_INDENT_BY_ONE) != 0) {
+ alignment.breakIndentationLevel= indentationLevel + indentSize;
+ } else {
+ alignment.breakIndentationLevel= indentationLevel +
+ continuationIndent * indentSize;
+ }
+ alignment.update();
+ break;
+ case STPAlignment.CHUNK_FIELD:
+ if ((mode & STPAlignment.M_INDENT_BY_ONE) != 0) {
+ alignment.breakIndentationLevel= current.originalIndentationLevel +
+ indentSize;
+ } else {
+ alignment.breakIndentationLevel= current.originalIndentationLevel +
+ continuationIndent * indentSize;
+ }
+ alignment.update();
+ break;
+ }
+ break;
+ }
+ }
+ }
+ return alignment;
+ }
+
+ public STPAlignment createMemberAlignment(String name, int mode, int count, int sourceRestart) {
+ STPAlignment alignment= createAlignment(name, mode, STPAlignment.R_INNERMOST, count, sourceRestart);
+ alignment.breakIndentationLevel= indentationLevel;
+ return alignment;
+ }
+
+ public void enterAlignment(STPAlignment alignment) {
+ alignment.enclosing= currentAlignment;
+ currentAlignment= alignment;
+ }
+
+ public void enterMemberAlignment(STPAlignment alignment) {
+ alignment.enclosing= memberAlignment;
+ memberAlignment= alignment;
+ }
+
+ public void exitAlignment(STPAlignment alignment, boolean discardAlignment) {
+ STPAlignment current= currentAlignment;
+ while (current != null) {
+ if (current == alignment)
+ break;
+ current= current.enclosing;
+ }
+ if (current == null) {
+ throw new AbortFormatting("could not find matching alignment: " + alignment); //$NON-NLS-1$
+ }
+ indentationLevel= alignment.location.outputIndentationLevel;
+ numberOfIndentations= alignment.location.numberOfIndentations;
+ if (discardAlignment) {
+ currentAlignment= alignment.enclosing;
+ }
+ }
+
+ public void exitMemberAlignment(STPAlignment alignment) {
+ STPAlignment current= memberAlignment;
+ while (current != null) {
+ if (current == alignment)
+ break;
+ current= current.enclosing;
+ }
+ if (current == null) {
+ throw new AbortFormatting("could not find matching alignment: " + alignment); //$NON-NLS-1$
+ }
+ indentationLevel= current.location.outputIndentationLevel;
+ numberOfIndentations= current.location.numberOfIndentations;
+ memberAlignment= current.enclosing;
+ }
+
+ public STPAlignment getAlignment(String name) {
+ if (currentAlignment != null) {
+ return currentAlignment.getAlignment(name);
+ }
+ return null;
+ }
+
+ private int getIndentationOfOffset(int offset) {
+ int beginningOfLine = getLineStart(offset);
+ int indent = 0;
+ for (int i= beginningOfLine; i < offset; i++) {
+ indent = computeIndentation(scanner.source[i], indent);
+ }
+ return indent;
+ }
+
+ /**
+ * Computes indentation after applying a character at a given indentation position.
+ * @param text the text to be applied.
+ * @param indent the initial indentation.
+ * @return the resulting indentation.
+ */
+ private int computeIndentation(char c, int indent) {
+ switch (c) {
+ case '\t':
+ return tabLength > 0 ? indent + tabLength - indent % tabLength : indent;
+ case '\r':
+ case '\n':
+ return 0;
+ default:
+ return indent + 1;
+ }
+ }
+
+ /**
+ * Computes indentation after applying a given text at a given indentation position.
+ * @param text the text to be applied.
+ * @param indent the initial indentation.
+ * @return the resulting indentation.
+ */
+ private int computeIndentation(char[] text, int indent) {
+ if (text == null)
+ return indent;
+ int length = text.length;
+ for (int i = 0; i < length; i++) {
+ indent = computeIndentation(text[i], indent);
+ }
+ return indent;
+ }
+
+ private int computeIndentation(CharSequence text, int indent) {
+ if (text == null)
+ return indent;
+ int length = text.length();
+ for (int i = 0; i < length; i++) {
+ indent = computeIndentation(text.charAt(i), indent);
+ }
+ return indent;
+ }
+
+ public String getEmptyLines(int linesNumber) {
+ StringBuilder buffer= new StringBuilder();
+ if (lastNumberOfNewLines == 0) {
+ linesNumber++; // add an extra line breaks
+ for (int i= 0; i < linesNumber; i++) {
+ if (indentEmptyLines)
+ printIndentationIfNecessary(buffer);
+ buffer.append(lineSeparator);
+ }
+ lastNumberOfNewLines += linesNumber;
+ line += linesNumber;
+ column= 1;
+ needSpace= false;
+ pendingSpace= false;
+ } else if (lastNumberOfNewLines == 1) {
+ for (int i= 0; i < linesNumber; i++) {
+ if (indentEmptyLines)
+ printIndentationIfNecessary(buffer);
+ buffer.append(lineSeparator);
+ }
+ lastNumberOfNewLines += linesNumber;
+ line += linesNumber;
+ column= 1;
+ needSpace= false;
+ pendingSpace= false;
+ } else {
+ if ((lastNumberOfNewLines - 1) >= linesNumber) {
+ // there is no need to add new lines
+ return EMPTY_STRING;
+ }
+ final int realNewLineNumber= linesNumber - lastNumberOfNewLines + 1;
+ for (int i= 0; i < realNewLineNumber; i++) {
+ if (indentEmptyLines)
+ printIndentationIfNecessary(buffer);
+ buffer.append(lineSeparator);
+ }
+ lastNumberOfNewLines += realNewLineNumber;
+ line += realNewLineNumber;
+ column= 1;
+ needSpace= false;
+ pendingSpace= false;
+ }
+ return String.valueOf(buffer);
+ }
+
+ public OptimizedReplaceEdit getLastEdit() {
+ if (editsIndex > 0) {
+ return edits[editsIndex - 1];
+ }
+ return null;
+ }
+
+ STPAlignment getMemberAlignment() {
+ return memberAlignment;
+ }
+
+ public String getNewLine() {
+ if (lastNumberOfNewLines >= 1) {
+ column= 1; // Ensure that the scribe is at the beginning of a new line
+ return EMPTY_STRING;
+ }
+ line++;
+ lastNumberOfNewLines= 1;
+ column= 1;
+ needSpace= false;
+ pendingSpace= false;
+ return lineSeparator;
+ }
+
+ /**
+ * Returns next indentation level based on column estimated position (if
+ * column is not indented, then uses indentationLevel)
+ */
+ public int getNextIndentationLevel(int someColumn) {
+ int indent= someColumn - 1;
+ if (indent == 0)
+ return indentationLevel;
+ if (tabChar == STPDefaultCodeFormatterOptions.TAB && !useTabsOnlyForLeadingIndents) {
+ // Round up to a multiple of indentationSize.
+ indent += indentationSize - 1;
+ return indent - indent % indentationSize;
+ } else {
+ return indent;
+ }
+ }
+
+ private String getPreserveEmptyLines(int count) {
+ if (count == 0 && !preserveNewLines) {
+ // preserve line breaks in wrapping if specified
+ if (!preferences.join_wrapped_lines && lastNumberOfNewLines == 0) {
+ // Create new line
+ StringBuilder tempBuffer = new StringBuilder();
+ tempBuffer.append(getNewLine());
+
+ if (currentAlignment != null && !formatBrace) {
+ indentationLevel = currentAlignment.breakIndentationLevel;
+ }
+
+ // Set the flag to indicate that a specific indentation is currently in used
+ preserveLineBreakIndentation = true;
+
+ // Print the computed indentation in the buffer
+ printIndentationIfNecessary(tempBuffer);
+
+ return tempBuffer.toString();
+ }
+ return EMPTY_STRING;
+ }
+ if (preferences.number_of_empty_lines_to_preserve != 0) {
+ int linesToPreserve= Math.min(count, preferences.number_of_empty_lines_to_preserve);
+ return getEmptyLines(linesToPreserve);
+ } else if (preserveNewLines) {
+ return getNewLine();
+ }
+ return EMPTY_STRING;
+ }
+
+ public TextEdit getRootEdit() {
+ MultiTextEdit edit= null;
+ int length= textRegionEnd - textRegionStart;
+ if (textRegionStart <= 0) {
+ if (length <= 0) {
+ edit= new MultiTextEdit(0, 0);
+ } else {
+ edit= new MultiTextEdit(0, textRegionEnd);
+ }
+ } else {
+ edit= new MultiTextEdit(textRegionStart, length);
+ }
+ for (int i= 0, max= editsIndex; i < max; i++) {
+ OptimizedReplaceEdit currentEdit= edits[i];
+ if (isValidEdit(currentEdit)) {
+ edit.addChild(new ReplaceEdit(currentEdit.offset, currentEdit.length, currentEdit.replacement));
+ }
+ }
+ edits= null;
+ return edit;
+ }
+
+ public void handleLineTooLong() {
+ // Search for closest breakable alignment, using tie-breaking rules.
+ // Look for innermost breakable one.
+ int relativeDepth= 0;
+ STPAlignment targetAlignment= currentAlignment;
+ while (targetAlignment != null && targetAlignment.tieBreakRule == STPAlignment.R_INNERMOST) {
+ if (targetAlignment.couldBreak()) {
+ throwAlignmentException(AlignmentException.LINE_TOO_LONG, relativeDepth);
+ }
+ targetAlignment= targetAlignment.enclosing;
+ relativeDepth++;
+ }
+
+ // Look for outermost breakable one.
+ relativeDepth= 0;
+ int outerMostDepth= -1;
+ targetAlignment= currentAlignment;
+ while (targetAlignment != null) {
+ if (targetAlignment.tieBreakRule == STPAlignment.R_OUTERMOST && targetAlignment.couldBreak()) {
+ outerMostDepth= relativeDepth;
+ }
+ targetAlignment= targetAlignment.enclosing;
+ relativeDepth++;
+ }
+ if (outerMostDepth >= 0) {
+ throwAlignmentException(AlignmentException.LINE_TOO_LONG, outerMostDepth);
+ }
+
+ // Look for innermost breakable one but don't stop if we encounter a R_OUTERMOST
+ // tie-breaking rule.
+ relativeDepth= 0;
+ targetAlignment= currentAlignment;
+ while (targetAlignment != null) {
+ if (targetAlignment.couldBreak()) {
+ throwAlignmentException(AlignmentException.LINE_TOO_LONG, relativeDepth);
+ }
+ targetAlignment= targetAlignment.enclosing;
+ relativeDepth++;
+ }
+ // Did not find any breakable location - proceed
+ }
+
+ private void throwAlignmentException(int kind, int relativeDepth) {
+ AlignmentException e= new AlignmentException(kind, relativeDepth);
+ currentAlignmentException= e;
+ throw e;
+ }
+
+ public void indent() {
+ if (shouldSkip(scanner.getCurrentPosition())) {
+ fSkippedIndentations++;
+ return;
+ }
+ indentationLevel += indentationSize;
+ numberOfIndentations++;
+ }
+
+ /**
+ * @param translationUnitSource
+ */
+ public void initializeScanner(char[] translationUnitSource) {
+ scanner.setSource(translationUnitSource);
+ scannerEndPosition= translationUnitSource.length;
+ scanner.resetTo(0, scannerEndPosition);
+ edits= new OptimizedReplaceEdit[INITIAL_SIZE];
+ // Locate line breaks.
+ lineOffsets = new int[200];
+ numLines = 0;
+ lineOffsets[numLines++] = 0;
+ for (int i = 0; i < translationUnitSource.length; i++) {
+ if (translationUnitSource[i] == '\n') {
+ int len = lineOffsets.length;
+ if (numLines >= len)
+ System.arraycopy(lineOffsets, 0, lineOffsets = new int[len + (len + 1) / 2], 0, len);
+ lineOffsets[numLines++] = i + 1;
+ }
+ }
+ }
+
+ /**
+ * @param list
+ */
+ public void setSkipPositions(List<Position> list) {
+ fSkipPositions= list;
+ skipOverInactive= !list.isEmpty();
+ }
+
+ /**
+ * Returns offset of the start of the line containing a given offset.
+ */
+ private int getLineStart(int offset) {
+ // Binary search
+ int down = 0;
+ int up = numLines;
+ while (true) {
+ int mid = (down + up) / 2;
+ int lineOffset = lineOffsets[mid];
+ if (mid == down) {
+ return lineOffset;
+ }
+ if (lineOffset > offset) {
+ up = mid;
+ } else {
+ down = mid;
+ }
+ }
+ }
+
+ private boolean isOnFirstColumn(int offset) {
+ return getLineStart(offset) == offset;
+ }
+
+ private boolean isValidEdit(OptimizedReplaceEdit edit) {
+ final int editLength= edit.length;
+ final int editReplacementLength= edit.replacement.length();
+ final int editOffset= edit.offset;
+ if (editLength != 0) {
+ if (textRegionStart <= editOffset && editOffset + editLength <= textRegionEnd) {
+ if (editReplacementLength != 0 && editLength == editReplacementLength) {
+ for (int i= editOffset, max= editOffset + editLength; i < max; i++) {
+ if (scanner.source[i] != edit.replacement.charAt(i - editOffset)) {
+ return true;
+ }
+ }
+ return false;
+ } else {
+ return true;
+ }
+ } else if (editOffset + editLength == textRegionStart) {
+ int i= editOffset;
+ for (int max= editOffset + editLength; i < max; i++) {
+ int replacementStringIndex= i - editOffset;
+ if (replacementStringIndex >= editReplacementLength
+ || scanner.source[i] != edit.replacement.charAt(replacementStringIndex)) {
+ break;
+ }
+ }
+ if (i - editOffset != editReplacementLength && i != editOffset + editLength - 1) {
+ edit.offset= textRegionStart;
+ edit.length= 0;
+ edit.replacement= edit.replacement.substring(i - editOffset);
+ return true;
+ }
+ }
+ } else if (textRegionStart <= editOffset && editOffset < textRegionEnd) {
+ return true;
+ } else if (editOffset == scannerEndPosition && editOffset == textRegionEnd) {
+ return true;
+ }
+ return false;
+ }
+
+ private void preserveEmptyLines(int count, int insertPosition) {
+ if (count > 0) {
+ if (preferences.number_of_empty_lines_to_preserve != 0) {
+ int linesToPreserve= Math.min(count, preferences.number_of_empty_lines_to_preserve);
+ printEmptyLines(linesToPreserve, insertPosition);
+ } else {
+ printNewLine(insertPosition);
+ }
+ } else {
+ printNewLine(insertPosition);
+ }
+ }
+
+ public void printRaw(int startOffset, int length) {
+ if (length <= 0) {
+ return;
+ }
+ int currentPosition= scanner.getCurrentPosition();
+ if (shouldSkip(currentPosition)) {
+ return;
+ }
+ if (startOffset > currentPosition) {
+ printComment();
+ currentPosition= scanner.getCurrentPosition();
+ }
+ if (startOffset + length < currentPosition) {
+ return; // Don't move backwards
+ }
+ boolean savedPreserveNL= preserveNewLines;
+ boolean savedSkipOverInactive= skipOverInactive;
+ int savedScannerEndPos= scannerEndPosition;
+ preserveNewLines= true;
+ skipOverInactive= false;
+ scannerEndPosition= startOffset + length;
+ try {
+ scanner.resetTo(Math.max(startOffset, currentPosition), startOffset + length);
+ int parenLevel= 0;
+ while (true) {
+ boolean hasWhitespace= printComment();
+ currentToken= scanner.nextToken();
+ if (currentToken == null) {
+ if (hasWhitespace) {
+ space();
+ }
+ break;
+ }
+ if (pendingSpace) {
+ addInsertEdit(scanner.getCurrentTokenStartPosition(), SPACE);
+ pendingSpace= false;
+ needSpace= false;
+ }
+ switch (currentToken.type) {
+ case Token.tLBRACE: {
+ scanner.resetTo(scanner.getCurrentTokenStartPosition(), scannerEndPosition);
+ formatOpeningBrace(preferences.brace_position_for_block,
+ preferences.insert_space_before_opening_brace_in_block);
+ if (preferences.indent_statements_compare_to_block) {
+ indent();
+ }
+ break;
+ }
+ case Token.tRBRACE: {
+ scanner.resetTo(scanner.getCurrentTokenStartPosition(), scannerEndPosition);
+ if (preferences.indent_statements_compare_to_block) {
+ unIndent();
+ }
+ formatClosingBrace(preferences.brace_position_for_block);
+ break;
+ }
+ case Token.tLPAREN:
+ ++parenLevel;
+ print(currentToken.getLength(), hasWhitespace);
+ if (parenLevel > 0) {
+ indentForContinuation();
+ if (column <= indentationLevel) {
+ // HACK: avoid indent in same line
+ column= indentationLevel + 1;
+ }
+ }
+ break;
+ case Token.tRPAREN:
+ --parenLevel;
+ if (parenLevel >= 0) {
+ unIndentForContinuation();
+ }
+ print(currentToken.getLength(), hasWhitespace);
+ break;
+ case Token.tSEMI:
+ print(currentToken.getLength(), preferences.insert_space_before_semicolon);
+ break;
+ case Token.t_catch:
+ case Token.t_else:
+ if (preferences.insert_new_line_before_else_in_if_statement) {
+ printNewLine(currentToken.offset);
+ } else {
+ hasWhitespace= true;
+ }
+ print(currentToken.getLength(), hasWhitespace);
+ break;
+ default:
+ if (currentToken.isVisibilityModifier()
+ && !preferences.indent_access_specifier_compare_to_type_header) {
+ int indentLevel= indentationLevel;
+ if (indentationLevel > 0)
+ unIndent();
+ print(currentToken.getLength(), hasWhitespace);
+ while (indentationLevel < indentLevel) {
+ indent();
+ }
+ } else {
+ print(currentToken.getLength(), hasWhitespace);
+ }
+ }
+ hasWhitespace= false;
+ }
+ } finally {
+ scannerEndPosition= savedScannerEndPos;
+ scanner.resetTo(startOffset + length, scannerEndPosition);
+ skipOverInactive= savedSkipOverInactive;
+ preserveNewLines= savedPreserveNL;
+ }
+ }
+
+ public void indentForContinuation() {
+ for (int i= 0; i < preferences.continuation_indentation; i++) {
+ indent();
+ }
+ }
+
+ public void unIndentForContinuation() {
+ for (int i= 0; i < preferences.continuation_indentation; i++) {
+ unIndent();
+ }
+ }
+
+ public void formatOpeningBrace(String bracePosition, boolean insertSpaceBeforeBrace) {
+ if (STPDefaultCodeFormatterConstants.NEXT_LINE.equals(bracePosition)) {
+ printNewLine();
+ } else if (STPDefaultCodeFormatterConstants.NEXT_LINE_SHIFTED.equals(bracePosition)) {
+ printNewLine();
+ indent();
+ }
+ printNextToken(Token.tLBRACE, insertSpaceBeforeBrace);
+
+ printTrailingComment();
+ }
+
+ public void formatClosingBrace(String block_brace_position) {
+ printNextToken(Token.tRBRACE);
+ printTrailingComment();
+ if (STPDefaultCodeFormatterConstants.NEXT_LINE_SHIFTED.equals(block_brace_position)) {
+ unIndent();
+ }
+ }
+
+ private void print(int length, boolean considerSpaceIfAny) {
+ if (checkLineWrapping && length + column - 1 > pageWidth) {
+ handleLineTooLong();
+ }
+ lastNumberOfNewLines= 0;
+ if (indentationLevel != 0) {
+ printIndentationIfNecessary();
+ }
+ if (considerSpaceIfAny) {
+ space();
+ }
+ if (pendingSpace) {
+ addInsertEdit(scanner.getCurrentTokenStartPosition(), SPACE);
+ }
+ if (checkLineWrapping && length + column - 1 > pageWidth) {
+ handleLineTooLong();
+ }
+ pendingSpace= false;
+ column += length;
+ needSpace= true;
+ }
+
+ private void printBlockComment(boolean forceNewLine) {
+ int currentTokenStartPosition= scanner.getCurrentTokenStartPosition();
+ int currentTokenEndPosition= scanner.getCurrentTokenEndPosition() + 1;
+
+ scanner.resetTo(currentTokenStartPosition, currentTokenEndPosition);
+ int currentCharacter;
+ boolean isNewLine= false;
+ int start= currentTokenStartPosition;
+ int nextCharacterStart= currentTokenStartPosition;
+ printIndentationIfNecessary();
+ if (pendingSpace) {
+ addInsertEdit(currentTokenStartPosition, SPACE);
+ }
+ needSpace= false;
+ pendingSpace= false;
+ int previousStart= currentTokenStartPosition;
+
+ while (nextCharacterStart <= currentTokenEndPosition && (currentCharacter= scanner.getNextChar()) != -1) {
+ nextCharacterStart= scanner.getCurrentPosition();
+
+ switch (currentCharacter) {
+ case '\r':
+ if (isNewLine) {
+ line++;
+ }
+ start= previousStart;
+ isNewLine= true;
+ if (scanner.getNextChar('\n')) {
+ currentCharacter= '\n';
+ nextCharacterStart= scanner.getCurrentPosition();
+ }
+ break;
+ case '\n':
+ if (isNewLine) {
+ line++;
+ }
+ start= previousStart;
+ isNewLine= true;
+ break;
+ default:
+ if (isNewLine) {
+ if (Character.isWhitespace((char) currentCharacter)) {
+ int previousStartPosition= scanner.getCurrentPosition();
+ while (currentCharacter != -1 && currentCharacter != '\r' &&
+ currentCharacter != '\n' &&
+ Character.isWhitespace((char) currentCharacter)) {
+ previousStart= nextCharacterStart;
+ previousStartPosition= scanner.getCurrentPosition();
+ currentCharacter= scanner.getNextChar();
+ nextCharacterStart= scanner.getCurrentPosition();
+ }
+ if (currentCharacter == '\r' || currentCharacter == '\n') {
+ nextCharacterStart= previousStartPosition;
+ }
+ }
+ column= 1;
+ line++;
+
+ StringBuilder buffer= new StringBuilder();
+ buffer.append(lineSeparator);
+ printIndentationIfNecessary(buffer);
+ buffer.append(' ');
+
+ addReplaceEdit(start, previousStart - 1, String.valueOf(buffer));
+ } else {
+ column += (nextCharacterStart - previousStart);
+ }
+ isNewLine= false;
+ }
+ previousStart= nextCharacterStart;
+ scanner.setCurrentPosition(nextCharacterStart);
+ }
+ lastNumberOfNewLines= 0;
+ needSpace= false;
+ scanner.resetTo(currentTokenEndPosition, scannerEndPosition);
+ if (forceNewLine) {
+ startNewLine();
+ }
+ }
+
+ private void printPreprocessorDirective() {
+ int currentTokenStartPosition= scanner.getCurrentTokenStartPosition();
+ int currentTokenEndPosition= scanner.getCurrentTokenEndPosition() + 1;
+
+ scanner.resetTo(currentTokenStartPosition, currentTokenEndPosition);
+ int currentCharacter;
+ boolean isNewLine= false;
+ int nextCharacterStart= currentTokenStartPosition;
+ needSpace= false;
+ pendingSpace= false;
+ int previousStart= currentTokenStartPosition;
+
+ while (nextCharacterStart <= currentTokenEndPosition &&
+ (currentCharacter= scanner.getNextChar()) != -1) {
+ nextCharacterStart= scanner.getCurrentPosition();
+
+ switch (currentCharacter) {
+ case '\r':
+ isNewLine= true;
+ if (scanner.getNextChar('\n')) {
+ currentCharacter= '\n';
+ nextCharacterStart= scanner.getCurrentPosition();
+ }
+ break;
+ case '\n':
+ isNewLine= true;
+ break;
+ default:
+ if (isNewLine) {
+ column= 1;
+ line++;
+ } else {
+ column += (nextCharacterStart - previousStart);
+ }
+ isNewLine= false;
+ }
+ previousStart= nextCharacterStart;
+ scanner.setCurrentPosition(nextCharacterStart);
+ }
+ lastNumberOfNewLines= isNewLine ? 1 : 0;
+ needSpace= false;
+ if (currentAlignment != null) {
+ indentationLevel= currentAlignment.breakIndentationLevel;
+ }
+ scanner.resetTo(currentTokenEndPosition, scannerEndPosition);
+ }
+
+ public void printEndOfTranslationUnit() {
+ int currentTokenStartPosition= scanner.getCurrentPosition();
+ if (currentTokenStartPosition <= scannerEndPosition) {
+ printRaw(currentTokenStartPosition, scannerEndPosition - currentTokenStartPosition + 1);
+ }
+ }
+
+ public boolean printComment() {
+ return printComment(NO_TRAILING_COMMENT);
+ }
+
+ /**
+ * Prints comment at the current position.
+ *
+ * @return {@code true} if a writespace character was encountered preceding the next token,
+ */
+ public boolean printComment(int trailing) {
+ // If we have a space between two tokens we ensure it will be dumped in the formatted
+ // string.
+ int currentTokenStartPosition= scanner.getCurrentPosition();
+ if (shouldSkip(currentTokenStartPosition)) {
+ return false;
+ }
+ boolean hasComment= false;
+ boolean hasLineComment= false;
+ boolean hasWhitespace= false;
+ char[] whiteSpaces= CharArrayUtils.EMPTY_CHAR_ARRAY;
+ int lines= 0;
+ while ((currentToken= scanner.nextToken()) != null) {
+ if (skipOverInactive) {
+ Position inactivePos= getInactivePosAt(scanner.getCurrentTokenStartPosition());
+ if (inactivePos != null) {
+ int startOffset= Math.min(scanner.getCurrentTokenStartPosition(),
+ inactivePos.getOffset());
+ int endOffset= Math.min(scannerEndPosition,
+ inactivePos.getOffset() + inactivePos.getLength());
+ if (startOffset < endOffset) {
+ int savedIndentLevel= indentationLevel;
+ scanner.resetTo(scanner.getCurrentTokenStartPosition(), scanner.eofPosition);
+ printRaw(startOffset, endOffset - startOffset);
+ while (indentationLevel > savedIndentLevel) {
+ unIndent();
+ }
+ while (indentationLevel < savedIndentLevel) {
+ indent();
+ }
+ scanner.resetTo(endOffset, scanner.eofPosition);
+ continue;
+ }
+ }
+ }
+ int tokenStartPosition = scanner.getCurrentTokenStartPosition();
+ switch (currentToken.type) {
+ case Token.tWHITESPACE:
+ whiteSpaces= scanner.getCurrentTokenSource();
+ int whitespacesEndPosition = scanner.getCurrentTokenEndPosition();
+ lines= 0;
+ for (int i= 0, max= whiteSpaces.length; i < max; i++) {
+ switch (whiteSpaces[i]) {
+ case '\r':
+ if ((i + 1) < max) {
+ if (whiteSpaces[i + 1] == '\n') {
+ i++;
+ }
+ }
+ lines++;
+ break;
+ case '\n':
+ lines++;
+ }
+ }
+ // If following token is a line comment on the same line or the line just after,
+ // then it might be not really formatted as a trailing comment.
+ boolean realTrailing = trailing != NO_TRAILING_COMMENT;
+ if (realTrailing && scanner.peekNextChar() == '/' && lines == 0) {
+ boolean canChangeTrailing = false;
+ // For basic trailing comment preceded by a line comment, then it depends on
+ // the comments relative position when following comment column (after having
+ // been rounded) is below the preceding one, then it becomes not a good idea
+ // to change the trailing flag.
+ if (trailing == BASIC_TRAILING_COMMENT && hasLineComment) {
+ int currentCommentIndentation = computeIndentation(whiteSpaces, 0);
+ int relativeIndentation =
+ currentCommentIndentation - lastLineComment.currentIndentation;
+ if (tabLength == 0) {
+ canChangeTrailing = relativeIndentation == 0;
+ } else {
+ canChangeTrailing = relativeIndentation > -tabLength;
+ }
+ }
+ // If the trailing can be changed, then look at the following tokens.
+ if (canChangeTrailing) {
+ int currentTokenPosition = scanner.getCurrentTokenStartPosition();
+ if (scanner.getNextToken() == Token.tLINECOMMENT) {
+ realTrailing = !hasLineComment;
+ switch (scanner.getNextToken()) {
+ case Token.tLINECOMMENT:
+ // At least two contiguous line comments.
+ // The formatter should not consider comments as trailing ones.
+ realTrailing = false;
+ break;
+ case Token.tWHITESPACE:
+ if (scanner.getNextToken() == Token.tLINECOMMENT) {
+ // At least two contiguous line comments.
+ // The formatter should not consider comments as trailing ones.
+ realTrailing = false;
+ }
+ break;
+ }
+ }
+ scanner.resetTo(currentTokenPosition, scanner.eofPosition);
+ scanner.getNextToken(); // Get current token again to restore the scanner state.
+ }
+ }
+ // Strategy to consume spaces and eventually leave at this stage
+ // depends on the fact that a trailing comment is expected or not
+ if (realTrailing) {
+ // If a line comment is consumed, no other comment can be on the same line after
+ if (hasLineComment) {
+ if (lines >= 1) {
+ currentTokenStartPosition = tokenStartPosition;
+ preserveEmptyLines(lines, currentTokenStartPosition);
+ addDeleteEdit(currentTokenStartPosition, whitespacesEndPosition);
+ scanner.resetTo(scanner.getCurrentPosition(), scannerEndPosition);
+ return hasWhitespace;
+ }
+ scanner.resetTo(currentTokenStartPosition, scannerEndPosition);
+ return hasWhitespace;
+ }
+ // If one or several new lines are consumed, following comments
+ // cannot be considered as trailing ones.
+ if (lines >= 1) {
+ if (hasComment) {
+ printNewLine(tokenStartPosition);
+ }
+ scanner.resetTo(currentTokenStartPosition, scannerEndPosition);
+ return hasWhitespace;
+ }
+ // Delete consumed white spaces
+ hasWhitespace = true;
+ currentTokenStartPosition = scanner.getCurrentPosition();
+ addDeleteEdit(tokenStartPosition, whitespacesEndPosition);
+ } else {
+ if (lines == 0) {
+ hasWhitespace= true;
+ addDeleteEdit(scanner.getCurrentTokenStartPosition(), scanner.getCurrentTokenEndPosition());
+ } else if (hasComment) {
+ if (lines == 1) {
+ printNewLine(scanner.getCurrentTokenStartPosition());
+ } else {
+ preserveEmptyLines(lines - 1, scanner.getCurrentTokenStartPosition());
+ }
+ addDeleteEdit(scanner.getCurrentTokenStartPosition(), scanner.getCurrentTokenEndPosition());
+ } else if (hasLineComment) {
+ preserveEmptyLines(lines, scanner.getCurrentTokenStartPosition());
+ addDeleteEdit(scanner.getCurrentTokenStartPosition(), scanner.getCurrentTokenEndPosition());
+ } else if (lines != 0 && (!preferences.join_wrapped_lines || preferences.number_of_empty_lines_to_preserve != 0)) {
+ String preservedEmptyLines= getPreserveEmptyLines(lines - 1);
+ addReplaceEdit(scanner.getCurrentTokenStartPosition(), scanner.getCurrentTokenEndPosition(),
+ preservedEmptyLines);
+ hasWhitespace= preservedEmptyLines.length() == 0;
+ } else {
+ addDeleteEdit(scanner.getCurrentTokenStartPosition(), scanner.getCurrentTokenEndPosition());
+ hasWhitespace= true;
+ }
+ }
+ currentTokenStartPosition= scanner.getCurrentPosition();
+ break;
+ case Token.tLINECOMMENT:
+ if (lines >= 1) {
+ if (lines > 1) {
+ preserveEmptyLines(lines - 1, scanner.getCurrentTokenStartPosition());
+ } else if (lines == 1) {
+ printNewLine(scanner.getCurrentTokenStartPosition());
+ }
+ } else if (hasWhitespace) {
+ // Look whether comments line may be contiguous or not
+ // Note that when preceding token is a comment line, then only one line
+ // is enough to have an empty line as the line end is included in the comment line.
+ // If comments are contiguous, store the white spaces to be able to compute
+ // the current comment indentation
+ if (lines > 1 || (lines == 1 && hasLineComment)) {
+ lastLineComment.contiguous = false;
+ }
+ lastLineComment.leadingSpaces = whiteSpaces;
+ lastLineComment.lines = lines;
+ }
+ whiteSpaces= CharArrayUtils.EMPTY_CHAR_ARRAY;
+ hasWhitespace= false;
+ printLineComment();
+ currentTokenStartPosition= scanner.getCurrentPosition();
+ hasLineComment= true;
+ lines= 0;
+ break;
+ case Token.tBLOCKCOMMENT:
+ if (lines >= 1) {
+ if (lines > 1) {
+ preserveEmptyLines(lines - 1, scanner.getCurrentTokenStartPosition());
+ } else if (lines == 1) {
+ printNewLine(scanner.getCurrentTokenStartPosition());
+ }
+ } else if (hasWhitespace) {
+ space();
+ }
+ whiteSpaces= CharArrayUtils.EMPTY_CHAR_ARRAY;
+ hasWhitespace= false;
+ printBlockComment(false);
+ currentTokenStartPosition= scanner.getCurrentPosition();
+ hasLineComment= false;
+ hasComment= true;
+ lines= 0;
+ break;
+ case Token.tPREPROCESSOR:
+ case Token.tPREPROCESSOR_DEFINE:
+ case Token.tPREPROCESSOR_INCLUDE:
+ if (column != 1)
+ printNewLine(scanner.getCurrentTokenStartPosition());
+ if (lines >= 1) {
+ if (lines > 1) {
+ preserveEmptyLines(lines - 1, scanner.getCurrentTokenStartPosition());
+ } else if (lines == 1) {
+ // printNewLine(scanner.getCurrentTokenStartPosition());
+ }
+ }
+ whiteSpaces= CharArrayUtils.EMPTY_CHAR_ARRAY;
+ hasWhitespace= false;
+ printPreprocessorDirective();
+ printNewLine();
+ currentTokenStartPosition= scanner.getCurrentPosition();
+ hasLineComment= false;
+ hasComment= false;
+ lines= 0;
+ break;
+ default:
+ // step back one token
+ scanner.resetTo(currentTokenStartPosition, scannerEndPosition);
+ return hasWhitespace;
+ }
+ }
+ scanner.resetTo(currentTokenStartPosition, scannerEndPosition);
+ return hasWhitespace;
+ }
+
+ /**
+ * @param offset
+ * @return
+ */
+ private Position getInactivePosAt(int offset) {
+ for (Iterator<Position> iter= fSkipPositions.iterator(); iter.hasNext();) {
+ Position pos= iter.next();
+ if (pos.includes(offset)) {
+ return pos;
+ }
+ }
+ return null;
+ }
+
+ private void printLineComment() {
+ int currentTokenStartPosition = scanner.getCurrentTokenStartPosition();
+ int currentTokenEndPosition = scanner.getCurrentTokenEndPosition() + 1;
+ scanner.resetTo(currentTokenStartPosition, currentTokenEndPosition);
+ int currentCharacter;
+ int start = currentTokenStartPosition;
+ int nextCharacterStart = currentTokenStartPosition;
+
+ // Print comment line indentation
+ int commentIndentationLevel;
+ boolean onFirstColumn = isOnFirstColumn(start);
+ if (indentationLevel == 0) {
+ commentIndentationLevel = column - 1;
+ } else {
+ if (onFirstColumn && preferences.never_indent_line_comments_on_first_column) {
+ commentIndentationLevel = column - 1;
+ } else {
+ // Indentation may be specific for contiguous comment
+ // see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=293300
+ if (lastLineComment.contiguous) {
+ // The leading spaces have been set while looping in the printComment(int) method
+ int currentCommentIndentation = computeIndentation(lastLineComment.leadingSpaces, 0);
+ // Keep the current comment indentation when over the previous contiguous line comment
+ // and the previous comment has not been re-indented
+ int relativeIndentation = currentCommentIndentation - lastLineComment.currentIndentation;
+ boolean similarCommentsIndentation = false;
+ if (tabLength == 0) {
+ similarCommentsIndentation = relativeIndentation == 0;
+ } else if (relativeIndentation > -tabLength) {
+ similarCommentsIndentation = relativeIndentation == 0
+ || currentCommentIndentation != 0 && lastLineComment.currentIndentation != 0;
+ }
+ if (similarCommentsIndentation && lastLineComment.indentation != indentationLevel) {
+ int currentIndentationLevel = indentationLevel;
+ indentationLevel = lastLineComment.indentation;
+ printIndentationIfNecessary();
+ indentationLevel = currentIndentationLevel;
+ commentIndentationLevel = lastLineComment.indentation;
+ } else {
+ printIndentationIfNecessary();
+ commentIndentationLevel = column - 1;
+ }
+ } else {
+ printIndentationIfNecessary();
+ commentIndentationLevel = column - 1;
+ }
+ }
+ }
+
+ // Prepare white space before the comment.
+ StringBuilder whitespace = null;
+ if (!lastLineComment.contiguous && commentIndentationLevel != indentationLevel &&
+ !(preferences.never_indent_line_comments_on_first_column && onFirstColumn)) {
+ whitespace = new StringBuilder();
+ int whitespaceStartPosition = currentTokenStartPosition - lastLineComment.leadingSpaces.length;
+ int indent = getIndentationOfOffset(whitespaceStartPosition);
+ int distance = computeIndentation(lastLineComment.leadingSpaces, indent) - indent;
+ if (preferences.comment_preserve_white_space_between_code_and_line_comment &&
+ distance >= preferences.comment_min_distance_between_code_and_line_comment) {
+ whitespace.append(lastLineComment.leadingSpaces);
+ } else {
+ for (int i = 0; i < preferences.comment_min_distance_between_code_and_line_comment; i++) {
+ whitespace.append(' ');
+ }
+ }
+ }
+
+ // Store line comment information
+ lastLineComment.currentIndentation = getIndentationOfOffset(currentTokenStartPosition);
+ lastLineComment.contiguous = true;
+
+ while (true) {
+ STPLocation location = new STPLocation(this, scanner.getCurrentPosition());
+ int commentIndent = commentIndentationLevel;
+
+ // Add pending space if necessary
+ if (whitespace != null) {
+ addInsertEdit(currentTokenStartPosition, whitespace);
+ commentIndent = computeIndentation(whitespace, commentIndentationLevel);
+ needSpace = false;
+ pendingSpace = false;
+ }
+ lastLineComment.indentation = commentIndent;
+
+ int previousStart = currentTokenStartPosition;
+
+ int indent = commentIndent;
+ loop: while (nextCharacterStart <= currentTokenEndPosition &&
+ (currentCharacter = scanner.getNextChar()) != -1) {
+ nextCharacterStart = scanner.getCurrentPosition();
+
+ switch (currentCharacter) {
+ case '\r':
+ case '\n':
+ start = previousStart;
+ break loop;
+ }
+ indent = computeIndentation((char) currentCharacter, indent);
+ previousStart = nextCharacterStart;
+ }
+
+ if (start != currentTokenStartPosition) {
+ // This means that the line comment doesn't end the file
+ addReplaceEdit(start, currentTokenEndPosition - 1, lineSeparator);
+ line++;
+ column = 1;
+ lastNumberOfNewLines = 1;
+ }
+ if (!checkLineWrapping || indent <= pageWidth || whitespace == null ||
+ commentIndent - commentIndentationLevel <= preferences.comment_min_distance_between_code_and_line_comment) {
+ break;
+ }
+
+ // Maximum line length was exceeded. Try to reduce white space before the comment by
+ // removing the last white space character.
+ whitespace.deleteCharAt(whitespace.length() - 1);
+ if (computeIndentation(lastLineComment.leadingSpaces, commentIndentationLevel) - commentIndentationLevel <
+ preferences.comment_min_distance_between_code_and_line_comment) {
+ // The white space shrank too much. Rebuild it to satisfy the minimum distance
+ // requirement.
+ whitespace.delete(0, whitespace.length());
+ for (int i = 0; i < preferences.comment_min_distance_between_code_and_line_comment; i++) {
+ whitespace.append(' ');
+ }
+ }
+ resetAt(location);
+ scanner.resetTo(location.inputOffset, scanner.eofPosition);
+ }
+
+ needSpace = false;
+ pendingSpace = false;
+ // realign to the proper value
+ if (currentAlignment != null) {
+ if (memberAlignment != null) {
+ // select the last alignment
+ if (currentAlignment.location.inputOffset > memberAlignment.location.inputOffset) {
+ if (currentAlignment.couldBreak() && currentAlignment.wasSplit) {
+ currentAlignment.performFragmentEffect();
+ }
+ } else {
+ indentationLevel = Math.max(indentationLevel, memberAlignment.breakIndentationLevel);
+ }
+ } else if (currentAlignment.couldBreak() && currentAlignment.wasSplit) {
+ currentAlignment.performFragmentEffect();
+ }
+ if (currentAlignment.name.equals(STPAlignment.BINARY_EXPRESSION) &&
+ currentAlignment.enclosing != null &&
+ currentAlignment.enclosing.equals(STPAlignment.BINARY_EXPRESSION) &&
+ indentationLevel < currentAlignment.breakIndentationLevel) {
+ indentationLevel = currentAlignment.breakIndentationLevel;
+ }
+ }
+ scanner.resetTo(currentTokenEndPosition, scannerEndPosition);
+ }
+
+ public void printEmptyLines(int linesNumber) {
+ printEmptyLines(linesNumber, scanner.getCurrentTokenEndPosition() + 1);
+ }
+
+ private void printEmptyLines(int linesNumber, int insertPosition) {
+ final String buffer= getEmptyLines(linesNumber);
+ if (!buffer.isEmpty()) {
+ addInsertEdit(insertPosition, buffer);
+ }
+ }
+
+ void printIndentationIfNecessary() {
+ if (column > indentationLevel)
+ return;
+ StringBuilder buffer= new StringBuilder();
+ printIndentationIfNecessary(buffer);
+ if (buffer.length() > 0) {
+ addInsertEdit(scanner.getCurrentTokenStartPosition(), buffer);
+ pendingSpace= false;
+ }
+ }
+
+ private void printIndentationIfNecessary(StringBuilder buffer) {
+ switch (tabChar) {
+ case STPDefaultCodeFormatterOptions.TAB:
+ boolean useTabsForLeadingIndents= useTabsOnlyForLeadingIndents;
+ int numberOfLeadingIndents= numberOfIndentations;
+ int indentationsAsTab= 0;
+ if (useTabsForLeadingIndents) {
+ while (column <= indentationLevel) {
+ if (indentationsAsTab < numberOfLeadingIndents) {
+ buffer.append('\t');
+ indentationsAsTab++;
+ int complement= tabLength - ((column - 1) % tabLength); // amount of space
+ column += complement;
+ needSpace= false;
+ } else {
+ buffer.append(' ');
+ column++;
+ needSpace= false;
+ }
+ }
+ } else {
+ while (column <= indentationLevel - indentationLevel % tabLength) {
+ buffer.append('\t');
+ int complement= tabLength - ((column - 1) % tabLength); // amount of space
+ column += complement;
+ needSpace= false;
+ }
+ while (column <= indentationLevel) {
+ buffer.append(' ');
+ column++;
+ needSpace= false;
+ }
+ }
+ break;
+ case STPDefaultCodeFormatterOptions.SPACE:
+ while (column <= indentationLevel) {
+ buffer.append(' ');
+ column++;
+ needSpace= false;
+ }
+ break;
+ case STPDefaultCodeFormatterOptions.MIXED:
+ useTabsForLeadingIndents= useTabsOnlyForLeadingIndents;
+ numberOfLeadingIndents= numberOfIndentations;
+ indentationsAsTab= 0;
+ if (useTabsForLeadingIndents) {
+ final int columnForLeadingIndents= numberOfLeadingIndents * indentationSize;
+ while (column <= indentationLevel) {
+ if (column <= columnForLeadingIndents) {
+ if ((column - 1 + tabLength) <= indentationLevel) {
+ buffer.append('\t');
+ column += tabLength;
+ } else if ((column - 1 + indentationSize) <= indentationLevel) {
+ // print one indentation
+ for (int i= 0, max= indentationSize; i < max; i++) {
+ buffer.append(' ');
+ column++;
+ }
+ } else {
+ buffer.append(' ');
+ column++;
+ }
+ } else {
+ for (int i= column, max= indentationLevel; i <= max; i++) {
+ buffer.append(' ');
+ column++;
+ }
+ }
+ needSpace= false;
+ }
+ } else {
+ while (column <= indentationLevel) {
+ if ((column - 1 + tabLength) <= indentationLevel) {
+ buffer.append('\t');
+ column += tabLength;
+ } else if ((column - 1 + indentationSize) <= indentationLevel) {
+ // print one indentation
+ for (int i= 0, max= indentationSize; i < max; i++) {
+ buffer.append(' ');
+ column++;
+ }
+ } else {
+ buffer.append(' ');
+ column++;
+ }
+ needSpace= false;
+ }
+ }
+ break;
+ }
+ }
+
+ public void enterNode() {
+ lastLineComment.contiguous = false;
+ }
+
+ public void startNewLine() {
+ if (column > 1) {
+ printNewLine();
+ }
+ }
+
+ public void printNewLine() {
+ printNewLine(scanner.getCurrentPosition());
+ }
+
+ public void printNewLine(int insertPosition) {
+ if (shouldSkip(scanner.getCurrentPosition())) {
+ return;
+ }
+ if (lastNumberOfNewLines >= 1) {
+ // Ensure that the scribe is at the beginning of a new line
+ // only if no specific indentation has been previously set.
+ if (!preserveLineBreakIndentation) {
+ column = 1;
+ }
+ preserveLineBreakIndentation = false;
+ return;
+ }
+ addInsertEdit(insertPosition, lineSeparator);
+ line++;
+ lastNumberOfNewLines= 1;
+ column= 1;
+ needSpace= false;
+ pendingSpace= false;
+ preserveLineBreakIndentation = false;
+ lastLineComment.contiguous = false;
+ }
+
+ public void printNextToken(int expectedTokenType) {
+ printNextToken(expectedTokenType, false);
+ }
+
+ public void printNextToken(int expectedTokenType, boolean considerSpaceIfAny) {
+ // Set brace flag, it's useful for the scribe while preserving line breaks
+ switch (expectedTokenType) {
+ case Token.tRBRACE:
+ case Token.tLBRACE:
+ formatBrace = true;
+ lastLineComment.contiguous = false;
+ }
+ try {
+ printComment();
+ if (shouldSkip(scanner.getCurrentPosition())) {
+ return;
+ }
+ currentToken= scanner.nextToken();
+ if (currentToken == null || expectedTokenType != currentToken.type) {
+ if (pendingSpace) {
+ addInsertEdit(scanner.getCurrentTokenStartPosition(), SPACE);
+ }
+ pendingSpace= false;
+ needSpace= true;
+ throw new AbortFormatting(
+ "[" + (line + 1) + "/" + column + "] Unexpected token type, expecting:" + //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$
+ expectedTokenType + ", actual:" + currentToken);//$NON-NLS-1$
+ }
+ print(currentToken.getLength(), considerSpaceIfAny);
+ } finally {
+ formatBrace = false;
+ }
+ }
+
+ public void printNextToken(int[] expectedTokenTypes) {
+ printNextToken(expectedTokenTypes, false);
+ }
+
+ public void printNextToken(int[] expectedTokenTypes, boolean considerSpaceIfAny) {
+ printComment();
+ if (shouldSkip(scanner.getCurrentPosition())) {
+ return;
+ }
+ currentToken= scanner.nextToken();
+ if (Arrays.binarySearch(expectedTokenTypes, currentToken.type) < 0) {
+ if (pendingSpace) {
+ addInsertEdit(scanner.getCurrentTokenStartPosition(), SPACE);
+ }
+ pendingSpace= false;
+ needSpace= true;
+ StringBuilder expectations= new StringBuilder(5);
+ for (int i= 0; i < expectedTokenTypes.length; i++) {
+ if (i > 0) {
+ expectations.append(',');
+ }
+ expectations.append(expectedTokenTypes[i]);
+ }
+ throw new AbortFormatting(
+ "[" + (line + 1) + "/" + column + "] unexpected token type, expecting:[" + expectations.toString() + "], actual:" + currentToken); //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$ //$NON-NLS-4$
+ }
+ print(currentToken.getLength(), considerSpaceIfAny);
+ }
+
+ private void printRuler(StringBuilder stringBuffer) {
+ for (int i= 0; i < pageWidth; i++) {
+ if ((i % tabLength) == 0) {
+ stringBuffer.append('+');
+ } else {
+ stringBuffer.append('-');
+ }
+ }
+ stringBuffer.append(lineSeparator);
+
+ for (int i= 0; i < (pageWidth / tabLength); i++) {
+ stringBuffer.append(i);
+ stringBuffer.append('\t');
+ }
+ }
+
+ public void printSpaces(int numSpaces) {
+ if (numSpaces > 0) {
+ int currentPosition= scanner.getCurrentPosition();
+ StringBuilder spaces = new StringBuilder(numSpaces);
+ for (int i = 0; i < numSpaces; i++) {
+ spaces.append(' ');
+ }
+ addInsertEdit(currentPosition, spaces);
+ pendingSpace= false;
+ needSpace= false;
+ }
+ }
+
+ public void printTrailingComment() {
+ printComment(BASIC_TRAILING_COMMENT);
+ }
+
+ void redoAlignment(AlignmentException e) {
+ if (e.relativeDepth > 0) { // if exception targets a distinct context
+ e.relativeDepth--; // record fact that current context got traversed
+ currentAlignment= currentAlignment.enclosing; // pop currentLocation
+ throw e; // rethrow
+ }
+ // Reset scribe/scanner to restart at this given location
+ resetAt(currentAlignment.location);
+ scanner.resetTo(currentAlignment.location.inputOffset, scanner.eofPosition);
+ // Clean alignment chunkKind so it will think it is a new chunk again
+ currentAlignment.chunkKind= 0;
+ currentAlignmentException= null;
+ }
+
+ void redoMemberAlignment(AlignmentException e) {
+ // Reset scribe/scanner to restart at this given location
+ resetAt(memberAlignment.location);
+ scanner.resetTo(memberAlignment.location.inputOffset, scanner.eofPosition);
+ // Clean alignment chunkKind so it will think it is a new chunk again
+ memberAlignment.chunkKind= 0;
+ currentAlignmentException= null;
+ }
+
+ public void reset() {
+ checkLineWrapping= true;
+ line= 0;
+ column= 1;
+ editsIndex= 0;
+ }
+
+ private void resetAt(STPLocation location) {
+ line= location.outputLine;
+ column= location.outputColumn;
+ indentationLevel= location.outputIndentationLevel;
+ needSpace= location.needSpace;
+ pendingSpace= location.pendingSpace;
+ numberOfIndentations= location.numberOfIndentations;
+ lastNumberOfNewLines= location.lastNumberOfNewLines;
+ editsIndex= location.editsIndex;
+ if (editsIndex > 0) {
+ edits[editsIndex - 1]= location.textEdit;
+ }
+ setTailFormatter(location.tailFormatter);
+ }
+
+ private void resize() {
+ System.arraycopy(edits, 0, (edits= new OptimizedReplaceEdit[editsIndex * 2]), 0, editsIndex);
+ }
+
+ public void space() {
+ if (!needSpace)
+ return;
+ if (shouldSkip(scanner.getCurrentPosition())) {
+ return;
+ }
+ lastNumberOfNewLines= 0;
+ pendingSpace= true;
+ column++;
+ needSpace= false;
+ }
+
+ public void undoSpace() {
+ if (pendingSpace) {
+ pendingSpace = false;
+ needSpace = true;
+ column--;
+ }
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder buffer= new StringBuilder();
+ buffer.append("(page width = " + pageWidth + ") - (tabChar = "); //$NON-NLS-1$//$NON-NLS-2$
+ switch (tabChar) {
+ case STPDefaultCodeFormatterOptions.TAB:
+ buffer.append("TAB"); //$NON-NLS-1$
+ break;
+ case STPDefaultCodeFormatterOptions.SPACE:
+ buffer.append("SPACE"); //$NON-NLS-1$
+ break;
+ default:
+ buffer.append("MIXED"); //$NON-NLS-1$
+ }
+ buffer
+ .append(") - (tabSize = " + tabLength + ")") //$NON-NLS-1$//$NON-NLS-2$
+ .append(lineSeparator)
+ .append("(line = " + line + ") - (column = " + column + ") - (identationLevel = " + indentationLevel + ")") //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+ .append(lineSeparator)
+ .append("(needSpace = " + needSpace + ") - (lastNumberOfNewLines = " + lastNumberOfNewLines + ") - (checkLineWrapping = " + checkLineWrapping + ")") //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+ .append(lineSeparator).append(
+ "==================================================================================") //$NON-NLS-1$
+ .append(lineSeparator);
+ printRuler(buffer);
+ return buffer.toString();
+ }
+
+ public void unIndent() {
+ if (shouldSkip(scanner.getCurrentPosition())) {
+ fSkippedIndentations--;
+ return;
+ }
+ indentationLevel-= indentationSize;
+ numberOfIndentations--;
+ }
+
+ /**
+ */
+ public boolean printModifiers() {
+ int currentTokenStartPosition= scanner.getCurrentPosition();
+ if (shouldSkip(currentTokenStartPosition)) {
+ return false;
+ }
+ boolean isFirstModifier= true;
+ boolean hasComment= false;
+ while ((currentToken= scanner.nextToken()) != null) {
+ switch (currentToken.type) {
+ case Token.t_typedef:
+ case Token.t_extern:
+ case Token.t_static:
+ case Token.t_auto:
+ case Token.t_register:
+ case Token.t_const:
+ case Token.t_signed:
+ case Token.t_unsigned:
+ case Token.t_volatile:
+ case Token.t_virtual:
+ case Token.t_mutable:
+ case Token.t_explicit:
+ case Token.t_friend:
+ case Token.t_inline:
+ case Token.t_restrict:
+ print(currentToken.getLength(), !isFirstModifier);
+ isFirstModifier= false;
+ currentTokenStartPosition= scanner.getCurrentPosition();
+ break;
+ case Token.tBLOCKCOMMENT:
+ printBlockComment(false);
+ currentTokenStartPosition= scanner.getCurrentPosition();
+ hasComment= true;
+ break;
+ case Token.tLINECOMMENT:
+ printLineComment();
+ currentTokenStartPosition= scanner.getCurrentPosition();
+ break;
+ case Token.tWHITESPACE:
+ addDeleteEdit(scanner.getCurrentTokenStartPosition(), scanner.getCurrentTokenEndPosition());
+ int count= 0;
+ char[] whiteSpaces= scanner.getCurrentTokenSource();
+ for (int i= 0, max= whiteSpaces.length; i < max; i++) {
+ switch (whiteSpaces[i]) {
+ case '\r':
+ if ((i + 1) < max) {
+ if (whiteSpaces[i + 1] == '\n') {
+ i++;
+ }
+ }
+ count++;
+ break;
+ case '\n':
+ count++;
+ }
+ }
+ if (count >= 1 && hasComment) {
+ printNewLine();
+ }
+ currentTokenStartPosition= scanner.getCurrentPosition();
+ hasComment= false;
+ break;
+ case Token.tPREPROCESSOR:
+ case Token.tPREPROCESSOR_DEFINE:
+ case Token.tPREPROCESSOR_INCLUDE:
+ if (column != 1)
+ printNewLine(scanner.getCurrentTokenStartPosition());
+ printPreprocessorDirective();
+ printNewLine();
+ currentTokenStartPosition= scanner.getCurrentPosition();
+ hasComment= false;
+ break;
+ default:
+ if (currentToken.getType() == Token.tIDENTIFIER) {
+ if (currentToken.getText().startsWith("__")) { //$NON-NLS-1$
+ // assume this is a declspec modifier
+ print(currentToken.getLength(), !isFirstModifier);
+ isFirstModifier= false;
+ currentTokenStartPosition= scanner.getCurrentPosition();
+ if ((currentToken= scanner.nextToken()) != null) {
+ if (currentToken.getType() == Token.tLPAREN) {
+ if (skipToToken(Token.tRPAREN)) {
+ currentToken= scanner.nextToken();
+ currentToken= scanner.nextToken();
+ currentTokenStartPosition= scanner.getCurrentPosition();
+ }
+ }
+ }
+ break;
+ }
+ }
+ // Step back one token
+ scanner.resetTo(currentTokenStartPosition, scannerEndPosition);
+ return !isFirstModifier;
+ }
+ }
+ return !isFirstModifier;
+ }
+
+ /**
+ * Skips to the next occurrence of the given token type.
+ * If successful, the next token will be the expected token,
+ * otherwise the scanner position is left unchanged.
+ *
+ * @param expectedTokenType
+ * @return <code>true</code> if a matching token was skipped to
+ */
+ public boolean skipToToken(int expectedTokenType) {
+ int skipStart= scanner.getCurrentPosition();
+ if (shouldSkip(skipStart)) {
+ return true;
+ }
+ int tokenStart = findToken(expectedTokenType);
+ if (tokenStart < 0) {
+ return false;
+ }
+ printRaw(skipStart, tokenStart - skipStart);
+ currentToken= scanner.nextToken();
+ scanner.resetTo(tokenStart, scannerEndPosition);
+ return true;
+ }
+
+ /**
+ * Searches for the next occurrence of the given token type.
+ * If successful, returns the offset of the found token, otherwise -1.
+ * The scanner position is left unchanged.
+ *
+ * @param tokenType type of the token to look for
+ * @return the position of the matching token, if found, otherwise -1.
+ */
+ public int findToken(int tokenType) {
+ return findToken(tokenType, scannerEndPosition - 1);
+ }
+
+ /**
+ * Searches for the next occurrence of the given token type.
+ * If successful, returns the offset of the found token, otherwise -1.
+ * The scanner position is left unchanged.
+ *
+ * @param tokenType type of the token to look for
+ * @param endPosition end position limiting the search
+ * @return the position of the matching token, if found, otherwise -1.
+ */
+ public int findToken(int tokenType, int endPosition) {
+ int startPosition= scanner.getCurrentPosition();
+ if (startPosition >= endPosition) {
+ return -1;
+ }
+ try {
+ int braceLevel= 0;
+ int parenLevel= 0;
+ switch (tokenType) {
+ case Token.tRBRACE:
+ ++braceLevel;
+ break;
+ case Token.tRPAREN:
+ ++parenLevel;
+ break;
+ }
+ Token token;
+ while ((token= scanner.nextToken()) != null) {
+ if (scanner.getCurrentTokenEndPosition() > endPosition)
+ return -1;
+
+ switch (token.type) {
+ case Token.tLBRACE:
+ if (tokenType != Token.tLBRACE) {
+ ++braceLevel;
+ }
+ break;
+ case Token.tRBRACE:
+ --braceLevel;
+ break;
+ case Token.tLPAREN:
+ if (tokenType != Token.tLPAREN) {
+ ++parenLevel;
+ }
+ break;
+ case Token.tRPAREN:
+ --parenLevel;
+ break;
+ case Token.tWHITESPACE:
+ case Token.tLINECOMMENT:
+ case Token.tBLOCKCOMMENT:
+ case Token.tPREPROCESSOR:
+ case Token.tPREPROCESSOR_DEFINE:
+ case Token.tPREPROCESSOR_INCLUDE:
+ continue;
+ }
+ if (braceLevel <= 0 && parenLevel <= 0) {
+ if (token.type == tokenType) {
+ return scanner.getCurrentTokenStartPosition();
+ }
+ }
+ if (braceLevel < 0 || parenLevel < 0) {
+ break;
+ }
+ }
+ } finally {
+ scanner.resetTo(startPosition, scannerEndPosition);
+ }
+ return -1;
+ }
+
+ /**
+ * Searches for the next occurrence of the given token type.
+ * If successful, returns the offset of the found token, otherwise -1.
+ * The scanner position is left unchanged.
+ *
+ * @param tokenType type of the token to look for
+ * @param startPosition position where to start the search
+ * @param endPosition end position limiting the search
+ * @return the position of the matching token, if found, otherwise -1.
+ */
+ public int findToken(int tokenType, int startPosition, int endPosition) {
+ int currentPosition= scanner.getCurrentPosition();
+ try {
+ scanner.resetTo(startPosition, scannerEndPosition);
+ return findToken(tokenType, endPosition);
+ } finally {
+ scanner.resetTo(currentPosition, scannerEndPosition);
+ }
+ }
+
+ public boolean printCommentPreservingNewLines() {
+ final boolean savedPreserveNL= preserveNewLines;
+ preserveNewLines= true;
+ try {
+ return printComment();
+ } finally {
+ preserveNewLines= savedPreserveNL;
+ }
+ }
+
+ boolean shouldSkip(int offset) {
+ return offset >= fSkipStartOffset && offset < fSkipEndOffset;
+ }
+
+ void skipRange(int offset, int endOffset) {
+ if (offset == fSkipStartOffset) {
+ return;
+ }
+ final int currentPosition= scanner.getCurrentPosition();
+ if (offset > currentPosition) {
+ fSkipStartOffset = Integer.MAX_VALUE;
+ printRaw(currentPosition, offset - currentPosition);
+ }
+ fSkipStartOffset= offset;
+ fSkipEndOffset= endOffset;
+ }
+
+ boolean skipRange() {
+ return fSkipEndOffset > 0;
+ }
+
+ void restartAtOffset(int offset) {
+ final int currentPosition= scanner.getCurrentPosition();
+ if (fSkipEndOffset > 0) {
+ fSkipStartOffset= Integer.MAX_VALUE;
+ fSkipEndOffset= 0;
+ while (fSkippedIndentations < 0) {
+ unIndent();
+ fSkippedIndentations++;
+ }
+ if (offset > currentPosition) {
+ printRaw(currentPosition, offset - currentPosition);
+ scanner.resetTo(offset, scannerEndPosition);
+ }
+ while (fSkippedIndentations > 0) {
+ indent();
+ fSkippedIndentations--;
+ }
+ } else if (offset > currentPosition) {
+ boolean hasSpace= printComment();
+ final int nextPosition= scanner.getCurrentPosition();
+ if (offset > nextPosition) {
+ if (hasSpace) {
+ space();
+ }
+ printRaw(nextPosition, offset - nextPosition);
+ scanner.resetTo(offset, scannerEndPosition);
+ }
+ }
+ }
+
+ /*
+ * Returns the tail formatter associated with the current alignment or, if there is no current
+ * alignment, with the scribe itself.
+ * @see #tailFormatter
+ */
+ public Runnable getTailFormatter() {
+ if (currentAlignment != null) {
+ return currentAlignment.tailFormatter;
+ } else {
+ return this.tailFormatter;
+ }
+ }
+
+ /*
+ * Returns the tail formatter associated with the current alignment or, if there is no current
+ * alignment, with the scribe itself. The tail formatter associated with the alignment or
+ * the scribe is set to {@code null}.
+ * @see #tailFormatter
+ */
+ public Runnable takeTailFormatter() {
+ Runnable formatter;
+ if (currentAlignment != null) {
+ formatter = currentAlignment.tailFormatter;
+ currentAlignment.tailFormatter = null;
+ } else {
+ formatter = this.tailFormatter;
+ this.tailFormatter = null;
+ }
+ return formatter;
+ }
+
+ /*
+ * Sets the tail formatter associated with the current alignment or, if there is no current
+ * alignment, with the scribe itself.
+ * @see #tailFormatter
+ */
+ public void setTailFormatter(Runnable tailFormatter) {
+ if (currentAlignment != null) {
+ currentAlignment.tailFormatter = tailFormatter;
+ } else {
+ this.tailFormatter = tailFormatter;
+ }
+ }
+
+ /*
+ * Runs the tail formatter associated with the current alignment or, if there is no current
+ * alignment, with the scribe itself.
+ * @see #tailFormatter
+ */
+ public void runTailFormatter() {
+ Runnable formatter = getTailFormatter();
+ if (formatter != null)
+ formatter.run();
+ }
+}
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPSymbols.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPSymbols.java
new file mode 100644
index 0000000000..993dfa2b16
--- /dev/null
+++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPSymbols.java
@@ -0,0 +1,79 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2010, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ * Sergey Prigogin (Google)
+ * Anton Leherbauer (Wind River Systems)
+ * Red Hat Inc. - modified for use in SystemTap
+ *******************************************************************************/
+package org.eclipse.linuxtools.internal.systemtap.ui.ide.editors.stp;
+
+/**
+ * Symbols for the heuristic STP scanner.
+ */
+public interface STPSymbols {
+ int TokenEOF= -1;
+ int TokenLBRACE= 1;
+ int TokenRBRACE= 2;
+ int TokenLBRACKET= 3;
+ int TokenRBRACKET= 4;
+ int TokenLPAREN= 5;
+ int TokenRPAREN= 6;
+ int TokenSEMICOLON= 7;
+ int TokenOTHER= 8;
+ int TokenCOLON= 9;
+ int TokenQUESTIONMARK= 10;
+ int TokenCOMMA= 11;
+ int TokenEQUAL= 12;
+ int TokenLESSTHAN= 13;
+ int TokenGREATERTHAN= 14;
+ int TokenDOT= 15;
+ int TokenMINUS= 16;
+ int TokenTILDE= 17;
+ int TokenSHIFTRIGHT= 18;
+ int TokenARROW= 19;
+ int TokenDOUBLECOLON= 20;
+ int TokenSHIFTLEFT= 21;
+ int TokenPLUS= 22;
+ int TokenAggregate= 23;
+ int TokenIF= 109;
+ int TokenDO= 1010;
+ int TokenFOR= 1011;
+ int TokenTRY= 1012;
+ int TokenCASE= 1013;
+ int TokenELSE= 1014;
+ int TokenBREAK= 1015;
+ int TokenCATCH= 1016;
+ int TokenWHILE= 1017;
+ int TokenRETURN= 1018;
+ int TokenSTATIC= 1019;
+ int TokenSWITCH= 1020;
+ int TokenGOTO= 1021;
+ int TokenDEFAULT= 1022;
+ int TokenPRIVATE= 1023;
+ int TokenPROTECTED= 1024;
+ int TokenPUBLIC= 1025;
+ int TokenNEW= 1026;
+ int TokenDELETE= 1027;
+ int TokenCLASS= 1028;
+ int TokenSTRUCT= 1029;
+ int TokenUNION= 1030;
+ int TokenENUM= 1031;
+ int TokenVIRTUAL= 1032;
+ int TokenNAMESPACE= 1033;
+ int TokenOPERATOR= 1034;
+ int TokenTHROW= 1035;
+ int TokenCONST= 1036;
+ int TokenEXTERN= 1037;
+ int TokenTYPEDEF= 1038;
+ int TokenUSING= 1039;
+ int TokenTEMPLATE= 1040;
+ int TokenTYPENAME= 1041;
+ int TokenFOREACH= 1042;
+ int TokenIDENT= 2000;
+}
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/Scanner.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/Scanner.java
new file mode 100644
index 0000000000..da23aeb708
--- /dev/null
+++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/Scanner.java
@@ -0,0 +1,224 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2011, 2013 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Anton Leherbauer (Wind River Systems) - initial API and implementation
+ * Sergey Prigogin (Google)
+ * Red Hat Inc. - modified for use in SystemTap
+ *******************************************************************************/
+package org.eclipse.linuxtools.internal.systemtap.ui.ide.editors.stp;
+
+import java.io.CharArrayReader;
+import java.io.Reader;
+
+/**
+ * A scanner operating on a character array and allowing to reposition the scanner.
+ *
+ * @since 4.0
+ */
+public class Scanner extends SimpleScanner {
+ public char[] source;
+ public int eofPosition;
+ public int startPosition;
+
+ public Scanner() {
+ setReuseToken(true);
+ setSplitPreprocessor(false);
+ }
+
+ @Override
+ protected void init(Reader reader, String filename) {
+ // not allowed
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Set the source text as character array.
+ *
+ * @param source the source text
+ */
+ public void setSource(char[] source) {
+ this.source= source;
+ fContext= new ScannerContext().initialize(new CharArrayReader(source));
+ startPosition= -1;
+ eofPosition= source.length;
+ }
+
+ /**
+ * Reset scanner to given inclusive start and end offsets
+ * @param start inclusive start offset
+ * @param end exclusive end offset
+ */
+ public void resetTo(int start, int end) {
+ Reader reader;
+ if (end >= source.length) {
+ reader= new CharArrayReader(source);
+ } else {
+ reader= new CharArrayReader(source, 0, Math.min(source.length, end));
+ }
+ fContext= new ScannerContext().initialize(reader, start);
+ startPosition= start;
+ if (source != null && source.length < end) {
+ eofPosition = source.length;
+ } else {
+ eofPosition = end;
+ }
+ }
+
+ /**
+ * Get the start offset of the current token.
+ * @return the start offset of the current token
+ */
+ public int getCurrentTokenStartPosition() {
+ return fCurrentToken.offset;
+ }
+
+ /**
+ * Get the inclusive end offset of the current token.
+ * @return the inclusive end offset of the current token
+ */
+ public int getCurrentTokenEndPosition() {
+ return getCurrentPosition() - 1;
+ }
+
+ /**
+ * Get the current scanner offset.
+ * @return the current scanner offset
+ */
+ public int getCurrentPosition() {
+ return fContext.getOffset() - fContext.undoStackSize();
+ }
+
+ /**
+ * Returns {@code true} if the scanner has reached the end of file.
+ */
+ public final boolean atEnd() {
+ return getCurrentPosition() >= eofPosition;
+ }
+
+ /**
+ * Get the next character.
+ * @return the next character
+ */
+ public int getNextChar() {
+ return getChar();
+ }
+
+ /**
+ * Move to next character iff it is equal to the given expected character.
+ * If the characters do not match, the scanner does not move forward.
+ *
+ * @param c the expected character
+ * @return <code>true</code> if the next character was the expected character
+ */
+ public boolean getNextChar(char c) {
+ if (c == getChar()) {
+ return true;
+ }
+ ungetChar(c);
+ return false;
+ }
+
+ /**
+ * Returns the next character without moving the pointer.
+ */
+ public int peekNextChar() {
+ int c = getChar();
+ ungetChar(c);
+ return c;
+ }
+
+ /**
+ * Set current scanner offset to given offset.
+ *
+ * @param nextCharacterStart the desired scanner offset
+ */
+ public void setCurrentPosition(int nextCharacterStart) {
+ int currentPos= getCurrentPosition();
+ int diff= currentPos - nextCharacterStart;
+ if (diff < 0) {
+ do {
+ getChar();
+ ++diff;
+ } while (diff < 0);
+ } else if (diff == 0) {
+ // no-op
+ } else if (diff > fTokenBuffer.length()) {
+ resetTo(nextCharacterStart, source.length);
+ } else /* if (diff <= fTokenBuffer.length()) */ {
+ while (diff > 0) {
+ if (fTokenBuffer.length() > 0) {
+ ungetChar(fTokenBuffer.charAt(fTokenBuffer.length() - 1));
+ }
+ --diff;
+ }
+ }
+ }
+
+ /**
+ * Get the text of the current token as a character array.
+ * @return the token text
+ */
+ public char[] getCurrentTokenSource() {
+ return fCurrentToken.getText().toCharArray();
+ }
+
+ /**
+ * Get the next token as token type constant.
+ *
+ * @return the next token type
+ */
+ public int getNextToken() {
+ Token token= nextToken();
+ if (token == null) {
+ return -1;
+ }
+ return token.type;
+ }
+
+ /**
+ * For debugging purposes.
+ */
+ @Override
+ public String toString() {
+ if (this.startPosition == this.source.length)
+ return "EOF\n\n" + new String(this.source); //$NON-NLS-1$
+ if (this.getCurrentPosition() > this.source.length)
+ return "behind the EOF\n\n" + new String(this.source); //$NON-NLS-1$
+
+ char front[] = new char[this.startPosition];
+ System.arraycopy(this.source, 0, front, 0, this.startPosition);
+
+ int middleLength = (this.getCurrentPosition() - 1) - this.startPosition + 1;
+ char middle[];
+ if (middleLength > -1) {
+ middle = new char[middleLength];
+ System.arraycopy(
+ this.source,
+ this.startPosition,
+ middle,
+ 0,
+ middleLength);
+ } else {
+ middle = new char[0];
+ }
+
+ char end[] = new char[this.source.length - (this.getCurrentPosition() - 1)];
+ System.arraycopy(
+ this.source,
+ (this.getCurrentPosition() - 1) + 1,
+ end,
+ 0,
+ this.source.length - (this.getCurrentPosition() - 1) - 1);
+
+ return new String(front)
+ + "\n===============================\nStarts here -->" //$NON-NLS-1$
+ + new String(middle)
+ + "<-- Ends here\n===============================\n" //$NON-NLS-1$
+ + new String(end);
+ }
+}
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/ScannerContext.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/ScannerContext.java
new file mode 100644
index 0000000000..eb5453b209
--- /dev/null
+++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/ScannerContext.java
@@ -0,0 +1,85 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2008, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial implementation
+ * Anton Leherbauer - adding tokens for preprocessing directives
+ * Markus Schorn - classification of preprocessing directives.
+ * Red Hat Inc. - modified for use in SystemTap
+ *******************************************************************************/
+package org.eclipse.linuxtools.internal.systemtap.ui.ide.editors.stp;
+
+import java.io.IOException;
+import java.io.Reader;
+import java.util.Stack;
+
+public class ScannerContext {
+ private Reader fReader;
+ private int fOffset;
+ private Stack<Integer> fUndo = new Stack<Integer>();
+
+ public ScannerContext() {
+ }
+
+ public ScannerContext initialize(Reader r) {
+ fReader = r;
+ fOffset = 0;
+ return this;
+ }
+
+ public ScannerContext initialize(Reader r, int offset) {
+ try {
+ r.skip(offset);
+ } catch (IOException exc) {
+ throw new RuntimeException(exc);
+ }
+ fReader = r;
+ fOffset = offset;
+ return this;
+ }
+
+ public int read() throws IOException {
+ ++fOffset;
+ return fReader.read();
+ }
+
+ /**
+ * Returns the offset.
+ * @return int
+ */
+ public final int getOffset() {
+ return fOffset;
+ }
+
+ /**
+ * Returns the reader.
+ * @return Reader
+ */
+ public final Reader getReader() {
+ return fReader;
+ }
+
+ public final int undoStackSize() {
+ return fUndo.size();
+ }
+
+ /**
+ * Returns the undo.
+ * @return int
+ */
+ public final int popUndo() {
+ return fUndo.pop().intValue();
+ }
+
+ /**
+ * Sets the undo.
+ * @param undo The undo to set
+ */
+ public void pushUndo(int undo) {
+ this.fUndo.push(new Integer(undo));
+ }
+}
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/SimpleScanner.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/SimpleScanner.java
new file mode 100644
index 0000000000..ffe32142d5
--- /dev/null
+++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/SimpleScanner.java
@@ -0,0 +1,963 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2011, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial implementation
+ * Anton Leherbauer - adding tokens for preprocessing directives
+ * Markus Schorn - classification of preprocessing directives.
+ * Red Hat Inc. - modified for use in SystemTap
+ *******************************************************************************/
+package org.eclipse.linuxtools.internal.systemtap.ui.ide.editors.stp;
+
+import java.io.IOException;
+import java.io.Reader;
+import java.util.HashMap;
+
+/**
+ * A C/C++ lexical scanner, which does no preprocessing,
+ * but tokenizes preprocessor directives, whitespace and comments.
+ *
+ * @since 4.0
+ */
+public class SimpleScanner {
+ private static final int EOFCHAR= -1;
+ protected static HashMap<String, Integer> fgKeywords= new HashMap<String, Integer>();
+
+ protected Token fCurrentToken;
+ protected ScannerContext fContext;
+ protected StringBuilder fTokenBuffer= new StringBuilder();
+ private int fPreprocessorToken= 0;
+ private boolean fReuseToken;
+ private boolean fSplitPreprocessor;
+ private final StringBuilder fUniversalCharBuffer= new StringBuilder();
+
+ public SimpleScanner() {
+ super();
+ }
+
+ public void setReuseToken(boolean val) {
+ fReuseToken= val;
+ if (val) {
+ fCurrentToken= new Token(0, null);
+ }
+ }
+
+ public void setSplitPreprocessor(boolean val) {
+ fSplitPreprocessor= val;
+ }
+
+ protected void init(Reader reader, String filename) {
+ fReuseToken= false;
+ fSplitPreprocessor= true;
+ fPreprocessorToken= 0;
+ fContext = new ScannerContext().initialize(reader);
+ }
+
+ public SimpleScanner initialize(Reader reader, String filename) {
+ init(reader, filename);
+ return this;
+ }
+
+ public void cleanup() {
+ fContext= null;
+ fTokenBuffer= new StringBuilder();
+ fCurrentToken= null;
+ }
+
+ private final void setCurrentToken(Token t) {
+ fCurrentToken = t;
+ }
+
+ private final Token newToken(int t) {
+ if (!fReuseToken) {
+ setCurrentToken(new Token(t, fTokenBuffer.toString(), fContext));
+ } else {
+ fCurrentToken.set(t, fTokenBuffer.toString(), fContext);
+ }
+ return fCurrentToken;
+ }
+
+ private Token newPreprocessorToken() {
+ if (fPreprocessorToken==0) {
+ fPreprocessorToken= categorizePreprocessor(fTokenBuffer);
+ }
+ return newToken(fPreprocessorToken);
+ }
+
+ private int categorizePreprocessor(StringBuilder text) {
+ boolean skipHash= true;
+ int i= 0;
+ for (; i < text.length(); i++) {
+ char c= text.charAt(i);
+ if (!Character.isWhitespace(c)) {
+ if (!skipHash) {
+ break;
+ }
+ skipHash= false;
+ if (c != '#') {
+ break;
+ }
+ }
+ }
+ String innerText= text.substring(i);
+ if (innerText.startsWith("include")) { //$NON-NLS-1$
+ return Token.tPREPROCESSOR_INCLUDE;
+ }
+ if (innerText.startsWith("define")) { //$NON-NLS-1$
+ return Token.tPREPROCESSOR_DEFINE;
+ }
+ if (innerText.startsWith("undef")) { //$NON-NLS-1$
+ return Token.tPREPROCESSOR_DEFINE;
+ }
+ return Token.tPREPROCESSOR;
+ }
+
+ protected final int getChar() {
+ return getChar(false);
+ }
+
+ private int getChar(boolean insideString) {
+ int c = EOFCHAR;
+
+ if (fContext.undoStackSize() != 0) {
+ c = fContext.popUndo();
+ } else {
+ try {
+ c = fContext.read();
+ } catch (IOException e) {
+ c = EOFCHAR;
+ }
+ }
+
+ fTokenBuffer.append((char) c);
+
+ if (!insideString && c == '\\') {
+ c = getChar(false);
+ if (c == '\r') {
+ c = getChar(false);
+ if (c == '\n') {
+ c = getChar(false);
+ }
+ } else if (c == '\n') {
+ c = getChar(false);
+ } else if (c == 'U' || c == 'u') {
+ fUniversalCharBuffer.setLength(0);
+ fUniversalCharBuffer.append('\\').append((char) c);
+ c = getUniversalCharacter();
+ } else {
+ ungetChar(c);
+ c = '\\';
+ }
+ }
+
+ return c;
+ }
+
+ private int getUniversalCharacter() {
+ int unicode = 0;
+ do {
+ int c = getChar(true);
+ int digit;
+ switch (c) {
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ digit = c - '0';
+ break;
+ case 'a':
+ case 'b':
+ case 'c':
+ case 'd':
+ case 'e':
+ case 'f':
+ digit = c - 'a' + 10;
+ break;
+ case 'A':
+ case 'B':
+ case 'C':
+ case 'D':
+ case 'E':
+ case 'F':
+ digit = c - 'A' + 10;
+ break;
+ default:
+ internalUngetChar(c);
+ return unicode;
+ }
+ fUniversalCharBuffer.append((char) c);
+ unicode <<= 4;
+ unicode += digit;
+ } while (true);
+ }
+
+ private void internalUngetChar(int c) {
+ fTokenBuffer.deleteCharAt(fTokenBuffer.length() - 1);
+ fContext.pushUndo(c);
+ }
+
+ protected void ungetChar(int c) {
+ if (c < 256 || c == fTokenBuffer.charAt(fTokenBuffer.length() - 1)) {
+ internalUngetChar(c);
+ } else if (fUniversalCharBuffer.length() > 0) {
+ char[] chs = fUniversalCharBuffer.toString().toCharArray();
+ for (int i = chs.length - 1; i >= 0; --i) {
+ internalUngetChar(chs[i]);
+ }
+ } else {
+ internalUngetChar(c);
+ }
+ }
+
+ public Token nextToken() {
+ fTokenBuffer.setLength(0);
+
+ boolean madeMistake = false;
+ int c = getChar();
+
+ while (c != EOFCHAR) {
+ if (fPreprocessorToken != 0) {
+ Token token= continuePPDirective(c);
+ if (token != null) {
+ return token;
+ }
+ }
+
+ if ((c == ' ') || (c == '\r') || (c == '\t') || (c == '\n')) {
+ do {
+ c = getChar();
+ } while ((c == ' ') || (c == '\r') || (c == '\t') || (c == '\n'));
+ ungetChar(c);
+ return newToken(Token.tWHITESPACE);
+ } else if (c == '"') {
+ matchStringLiteral();
+ return newToken(Token.tSTRING);
+ } else if (c == 'L' && !madeMistake) {
+ int oldChar = c;
+ c = getChar();
+ if (c != '"') {
+ // we have made a mistake
+ ungetChar(c);
+ c = oldChar;
+ madeMistake = true;
+ continue;
+ }
+
+ matchStringLiteral();
+ return newToken(Token.tLSTRING);
+ } else if (c == 'R' && !madeMistake) {
+ int oldChar = c;
+ c = getChar();
+ if (c != '"') {
+ // we have made a mistake
+ ungetChar(c);
+ c = oldChar;
+ madeMistake = true;
+ continue;
+ }
+
+ matchRawStringLiteral();
+ return newToken(Token.tRSTRING);
+ } else if (((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z')) || (c == '_') || (c > 255 && Character.isUnicodeIdentifierStart(c))) {
+ madeMistake = false;
+
+ c = getChar();
+
+ while (((c >= 'a') && (c <= 'z'))
+ || ((c >= 'A') && (c <= 'Z'))
+ || ((c >= '0') && (c <= '9'))
+ || (c == '_')
+ || (c > 255 && Character.isUnicodeIdentifierPart(c))) {
+ c = getChar();
+ }
+
+ ungetChar(c);
+
+ String ident = fTokenBuffer.toString();
+
+ Object tokenTypeObject;
+
+ tokenTypeObject = fgKeywords.get(ident);
+
+ int tokenType = Token.tIDENTIFIER;
+ if (tokenTypeObject != null)
+ tokenType = ((Integer)tokenTypeObject).intValue();
+
+ return newToken(tokenType);
+ } else if ((c >= '0') && (c <= '9') || c == '.') {
+ boolean hex = false;
+ boolean floatingPoint = c == '.';
+ boolean firstCharZero = c == '0';
+
+ c = getChar();
+
+ if (firstCharZero && c == 'x') {
+ hex = true;
+ c = getChar();
+ }
+
+ int digits= 0;
+
+ while ((c >= '0' && c <= '9') || (hex && ((c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F')))) {
+ ++digits;
+ c = getChar();
+ }
+
+ if (!hex) {
+ if (c == '*') {
+ if (floatingPoint && digits == 0) {
+ // encountered .*
+ return newToken(Token.tDOTSTAR);
+ }
+ } else if (c == '.') {
+ if (floatingPoint && digits == 0) {
+ // encountered ..
+ if ((c= getChar()) == '.') {
+ return newToken(Token.tELIPSE);
+ } else {
+ ungetChar(c);
+ ungetChar('.');
+ return newToken(Token.tDOT);
+ }
+ }
+
+ floatingPoint = true;
+ c = getChar();
+ while ((c >= '0' && c <= '9')) {
+ ++digits;
+ c = getChar();
+ }
+ } else if (digits > 0 && (c == 'e' || c == 'E')) {
+ floatingPoint = true;
+
+ // exponent type for floating point
+ c = getChar();
+
+ // optional + or -
+ if (c == '+' || c == '-') {
+ c = getChar();
+ }
+
+ // digit sequence of exponent part
+ while ((c >= '0' && c <= '9')) {
+ c = getChar();
+ }
+ }
+ }
+ if (floatingPoint) {
+ if (digits > 0) {
+ //floating-suffix
+ if (c == 'l' || c == 'L' || c == 'f' || c == 'F') {
+ c = getChar();
+ }
+ } else {
+ ungetChar(c);
+ return newToken(Token.tDOT);
+ }
+ } else {
+ //integer suffix
+ if (c == 'u' || c == 'U') {
+ c = getChar();
+ if (c == 'l' || c == 'L')
+ c = getChar();
+ } else if (c == 'l' || c == 'L') {
+ c = getChar();
+ if (c == 'u' || c == 'U')
+ c = getChar();
+ }
+ }
+
+ ungetChar(c);
+
+ int tokenType;
+ String result = fTokenBuffer.toString();
+
+ if (floatingPoint && result.equals(".")) //$NON-NLS-1$
+ tokenType = Token.tDOT;
+ else
+ tokenType = floatingPoint ? Token.tFLOATINGPT : Token.tINTEGER;
+
+ return newToken(tokenType);
+ } else if (c == '#') {
+ return matchPPDirective();
+ } else {
+ switch (c) {
+ case '\'':
+ matchCharLiteral();
+ return newToken(Token.tCHAR);
+
+ case ':':
+ c = getChar();
+ if (c == ':') {
+ return newToken(Token.tCOLONCOLON);
+ } else {
+ ungetChar(c);
+ return newToken(Token.tCOLON);
+ }
+ case ';':
+ return newToken(Token.tSEMI);
+ case ',':
+ return newToken(Token.tCOMMA);
+ case '?':
+ return newToken(Token.tQUESTION);
+ case '(':
+ return newToken(Token.tLPAREN);
+ case ')':
+ return newToken(Token.tRPAREN);
+ case '[':
+ return newToken(Token.tLBRACKET);
+ case ']':
+ return newToken(Token.tRBRACKET);
+ case '{':
+ return newToken(Token.tLBRACE);
+ case '}':
+ return newToken(Token.tRBRACE);
+ case '+':
+ c = getChar();
+ switch (c) {
+ case '=':
+ return newToken(Token.tPLUSASSIGN);
+ case '+':
+ return newToken(Token.tINCR);
+ default:
+ ungetChar(c);
+ return newToken(Token.tPLUS);
+ }
+ case '-':
+ c = getChar();
+ switch (c) {
+ case '=':
+ return newToken(Token.tMINUSASSIGN);
+ case '-':
+ return newToken(Token.tDECR);
+ case '>':
+ c = getChar();
+ switch (c) {
+ case '*':
+ return newToken(Token.tARROWSTAR);
+ default:
+ ungetChar(c);
+ return newToken(Token.tARROW);
+ }
+ default:
+ ungetChar(c);
+ return newToken(Token.tMINUS);
+ }
+ case '*':
+ c = getChar();
+ switch (c) {
+ case '=':
+ return newToken(Token.tSTARASSIGN);
+ default:
+ ungetChar(c);
+ return newToken(Token.tSTAR);
+ }
+ case '%':
+ c = getChar();
+ switch (c) {
+ case '=':
+ return newToken(Token.tMODASSIGN);
+ default:
+ ungetChar(c);
+ return newToken(Token.tMOD);
+ }
+ case '^':
+ c = getChar();
+ switch (c) {
+ case '=':
+ return newToken(Token.tXORASSIGN);
+ default:
+ ungetChar(c);
+ return newToken(Token.tXOR);
+ }
+ case '&':
+ c = getChar();
+ switch (c) {
+ case '=':
+ return newToken(Token.tAMPERASSIGN);
+ case '&':
+ return newToken(Token.tAND);
+ default:
+ ungetChar(c);
+ return newToken(Token.tAMPER);
+ }
+ case '|':
+ c = getChar();
+ switch (c) {
+ case '=':
+ return newToken(Token.tBITORASSIGN);
+ case '|':
+ return newToken(Token.tOR);
+ default:
+ ungetChar(c);
+ return newToken(Token.tBITOR);
+ }
+ case '~':
+ return newToken(Token.tCOMPL);
+ case '!':
+ c = getChar();
+ switch (c) {
+ case '=':
+ return newToken(Token.tNOTEQUAL);
+ default:
+ ungetChar(c);
+ return newToken(Token.tNOT);
+ }
+ case '=':
+ c = getChar();
+ switch (c) {
+ case '=':
+ return newToken(Token.tEQUAL);
+ default:
+ ungetChar(c);
+ return newToken(Token.tASSIGN);
+ }
+ case '<':
+ c = getChar();
+ switch (c) {
+ case '<':
+ c = getChar();
+ switch (c) {
+ case '=':
+ return newToken(Token.tSHIFTLASSIGN);
+ default:
+ ungetChar(c);
+ return newToken(Token.tSHIFTL);
+ }
+ case '=':
+ return newToken(Token.tLTEQUAL);
+ default:
+ ungetChar(c);
+ return newToken(Token.tLT);
+ }
+ case '>':
+ c = getChar();
+ switch (c) {
+ case '>':
+ c = getChar();
+ switch (c) {
+ case '=':
+ return newToken(Token.tSHIFTRASSIGN);
+ default:
+ ungetChar(c);
+ return newToken(Token.tSHIFTR);
+ }
+ case '=':
+ return newToken(Token.tGTEQUAL);
+ default:
+ ungetChar(c);
+ return newToken(Token.tGT);
+ }
+ case '.':
+ c = getChar();
+ switch (c) {
+ case '.':
+ c = getChar();
+ switch (c) {
+ case '.':
+ return newToken(Token.tELIPSE);
+ default:
+ break;
+ }
+ break;
+ case '*':
+ return newToken(Token.tDOTSTAR);
+ default:
+ ungetChar(c);
+ return newToken(Token.tDOT);
+ }
+ break;
+ case '/':
+ c = getChar();
+ switch (c) {
+ case '/': {
+ matchSinglelineComment();
+ return newToken(Token.tLINECOMMENT);
+ }
+ case '*': {
+ matchMultilineComment();
+ return newToken(Token.tBLOCKCOMMENT);
+ }
+ case '=':
+ return newToken(Token.tDIVASSIGN);
+ default:
+ ungetChar(c);
+ return newToken(Token.tDIV);
+ }
+ default:
+ // Bad character
+ return newToken(Token.tBADCHAR);
+ }
+ // throw EOF;
+ }
+ }
+
+ // we're done
+ // throw EOF;
+ return null;
+ }
+
+ private void matchCharLiteral() {
+ int c;
+ c = getChar(true);
+ int next = getChar(true);
+ if (c == '\\') {
+ if (next >= '0' && next <= '7') {
+ do {
+ next = getChar(true);
+ } while (next >= '0' && next <= '7');
+ } else if (next == 'x' || next == 'X' || next == 'u' || next == 'U') {
+ do {
+ next = getChar(true);
+ } while ((next >= '0' && next <= '9') || (next >= 'a' && next <= 'f')
+ || (next >= 'A' && next <= 'F'));
+ } else {
+ next = getChar(true);
+ }
+ }
+ if (next != '\'') {
+ ungetChar(next);
+ }
+ }
+
+ private void matchStringLiteral() {
+ // string
+ boolean escaped= false;
+ int c = getChar(true);
+
+ LOOP: for (;;) {
+ if (c == EOFCHAR)
+ break;
+ if (escaped) {
+ escaped= false;
+ int nc= getChar(true);
+ if (c=='\r' && nc=='\n') {
+ nc= getChar(true);
+ }
+ c= nc;
+ } else {
+ switch(c) {
+ case '\\':
+ escaped= true;
+ break;
+ case '"':
+ break LOOP;
+ case '\r':
+ case '\n':
+ // unterminated string constant
+ ungetChar(c);
+ break LOOP;
+ }
+ c = getChar(true);
+ }
+ }
+ }
+
+ private void matchRawStringLiteral() {
+ // raw-string R"<delim-opt>(string)<delim-opt>";
+ int c = getChar(false);
+ StringBuilder delim = new StringBuilder(12);
+ while (c != '(') {
+ if (c == EOFCHAR) {
+ return;
+ }
+ delim.append((char) c);
+ c = getChar(false);
+ }
+ int delimLen = delim.length();
+ c = getChar(false);
+ LOOP:
+ for (;;) {
+ if (c == EOFCHAR)
+ break;
+ if (c == ')') {
+ c = getChar(false);
+ int idx = 0;
+ while (idx < delimLen) {
+ if (c != delim.charAt(idx)) {
+ continue LOOP;
+ }
+ ++idx;
+ c = getChar(false);
+ }
+ if (c == '"')
+ break;
+ }
+ c = getChar(false);
+ }
+ }
+
+ /**
+ * Matches a preprocessor directive.
+ *
+ * @return a preprocessor token
+ */
+ private Token matchPPDirective() {
+ if (!fSplitPreprocessor) {
+ getRestOfPreprocessorLine();
+ return newToken(Token.tPREPROCESSOR);
+ }
+ return continuePPDirective(getChar());
+ }
+
+ private Token continuePPDirective(int c) {
+ boolean done= false;
+ while (!done) {
+ switch(c) {
+ case '\'':
+ if (fTokenBuffer.length() > 1) {
+ if (fPreprocessorToken == 0) {
+ fPreprocessorToken= categorizePreprocessor(fTokenBuffer);
+ }
+ ungetChar(c);
+ return newPreprocessorToken();
+ }
+ matchCharLiteral();
+ return newToken(Token.tCHAR);
+
+ case '"':
+ if (fTokenBuffer.length() > 1) {
+ if (fPreprocessorToken==0) {
+ fPreprocessorToken= categorizePreprocessor(fTokenBuffer);
+ }
+ if (fPreprocessorToken==Token.tPREPROCESSOR_INCLUDE) {
+ matchStringLiteral();
+ c= getChar();
+ break;
+ } else {
+ ungetChar(c);
+ return newPreprocessorToken();
+ }
+ }
+ matchStringLiteral();
+ return newToken(Token.tSTRING);
+ case '/': {
+ int next = getChar();
+ if (next == '/') {
+ Token result= null;
+ if (fTokenBuffer.length() > 2) {
+ ungetChar(next);
+ ungetChar(c);
+ result= newPreprocessorToken();
+ } else {
+ matchSinglelineComment();
+ result= newToken(Token.tLINECOMMENT);
+ }
+ fPreprocessorToken= 0;
+ return result;
+ }
+ if (next == '*') {
+ if (fTokenBuffer.length() > 2) {
+ ungetChar(next);
+ ungetChar(c);
+ return newPreprocessorToken();
+ }
+ // multiline comment
+ if (matchMultilineComment()) {
+ fPreprocessorToken= 0;
+ }
+ return newToken(Token.tBLOCKCOMMENT);
+ }
+ c = next;
+ break;
+ }
+ case '\n':
+ case '\r':
+ case EOFCHAR:
+ done= true;
+ break;
+ default:
+ c= getChar();
+ break;
+ }
+ }
+ ungetChar(c);
+ Token result= null;
+ if (fTokenBuffer.length() > 0) {
+ result= newPreprocessorToken();
+ }
+ fPreprocessorToken= 0;
+ return result;
+ }
+
+ /**
+ * Read until end of preprocessor directive.
+ */
+ private void getRestOfPreprocessorLine() {
+ int c = getChar();
+ while (true) {
+ while ((c != '\n') && (c != '\r') && (c != '/') && (c != '"') && (c != EOFCHAR)) {
+ c = getChar();
+ }
+ if (c == '/') {
+ // we need to peek ahead at the next character to see if
+ // this is a comment or not
+ int next = getChar();
+ if (next == '/') {
+ // single line comment
+ matchSinglelineComment();
+ break;
+ } else if (next == '*') {
+ // multiline comment
+ if (matchMultilineComment())
+ break;
+ else
+ c = getChar();
+ continue;
+ } else {
+ // we are not in a comment
+ c = next;
+ continue;
+ }
+ } else if (c == '"') {
+ matchStringLiteral();
+ c = getChar();
+ } else {
+ ungetChar(c);
+ break;
+ }
+ }
+ }
+
+ private void matchSinglelineComment() {
+ int c = getChar();
+ while (c != '\n' && c != EOFCHAR) {
+ c = getChar();
+ }
+ if (c == EOFCHAR) {
+ ungetChar(c);
+ }
+ }
+
+ private boolean matchMultilineComment() {
+ boolean encounteredNewline = false;
+ int state = 0;
+ int c = getChar();
+ while (state != 2 && c != EOFCHAR) {
+ if (c == '\n')
+ encounteredNewline = true;
+
+ switch (state) {
+ case 0 :
+ if (c == '*')
+ state = 1;
+ break;
+ case 1 :
+ if (c == '/')
+ state = 2;
+ else if (c != '*')
+ state = 0;
+ break;
+ }
+ c = getChar();
+ }
+ ungetChar(c);
+ return encounteredNewline;
+ }
+
+ static {
+ fgKeywords.put("and", new Integer(Token.t_and)); //$NON-NLS-1$
+ fgKeywords.put("and_eq", new Integer(Token.t_and_eq)); //$NON-NLS-1$
+ fgKeywords.put("asm", new Integer(Token.t_asm)); //$NON-NLS-1$
+ fgKeywords.put("auto", new Integer(Token.t_auto)); //$NON-NLS-1$
+ fgKeywords.put("bitand", new Integer(Token.t_bitand)); //$NON-NLS-1$
+ fgKeywords.put("bitor", new Integer(Token.t_bitor)); //$NON-NLS-1$
+ fgKeywords.put("bool", new Integer(Token.t_bool)); //$NON-NLS-1$
+ fgKeywords.put("break", new Integer(Token.t_break)); //$NON-NLS-1$
+ fgKeywords.put("case", new Integer(Token.t_case)); //$NON-NLS-1$
+ fgKeywords.put("catch", new Integer(Token.t_catch)); //$NON-NLS-1$
+ fgKeywords.put("char", new Integer(Token.t_char)); //$NON-NLS-1$
+ fgKeywords.put("class", new Integer(Token.t_class)); //$NON-NLS-1$
+ fgKeywords.put("compl", new Integer(Token.t_compl)); //$NON-NLS-1$
+ fgKeywords.put("const", new Integer(Token.t_const)); //$NON-NLS-1$
+ fgKeywords.put("const_cast", new Integer(Token.t_const_cast)); //$NON-NLS-1$
+ fgKeywords.put("continue", new Integer(Token.t_continue)); //$NON-NLS-1$
+ fgKeywords.put("default", new Integer(Token.t_default)); //$NON-NLS-1$
+ fgKeywords.put("delete", new Integer(Token.t_delete)); //$NON-NLS-1$
+ fgKeywords.put("do", new Integer(Token.t_do)); //$NON-NLS-1$
+ fgKeywords.put("double", new Integer(Token.t_double)); //$NON-NLS-1$
+ fgKeywords.put("dynamic_cast", new Integer(Token.t_dynamic_cast)); //$NON-NLS-1$
+ fgKeywords.put("else", new Integer(Token.t_else)); //$NON-NLS-1$
+ fgKeywords.put("enum", new Integer(Token.t_enum)); //$NON-NLS-1$
+ fgKeywords.put("explicit", new Integer(Token.t_explicit)); //$NON-NLS-1$
+ fgKeywords.put("export", new Integer(Token.t_export)); //$NON-NLS-1$
+ fgKeywords.put("extern", new Integer(Token.t_extern)); //$NON-NLS-1$
+ fgKeywords.put("false", new Integer(Token.t_false)); //$NON-NLS-1$
+ fgKeywords.put("float", new Integer(Token.t_float)); //$NON-NLS-1$
+ fgKeywords.put("for", new Integer(Token.t_for)); //$NON-NLS-1$
+ fgKeywords.put("friend", new Integer(Token.t_friend)); //$NON-NLS-1$
+ fgKeywords.put("goto", new Integer(Token.t_goto)); //$NON-NLS-1$
+ fgKeywords.put("if", new Integer(Token.t_if)); //$NON-NLS-1$
+ fgKeywords.put("inline", new Integer(Token.t_inline)); //$NON-NLS-1$
+ fgKeywords.put("int", new Integer(Token.t_int)); //$NON-NLS-1$
+ fgKeywords.put("long", new Integer(Token.t_long)); //$NON-NLS-1$
+ fgKeywords.put("mutable", new Integer(Token.t_mutable)); //$NON-NLS-1$
+ fgKeywords.put("namespace", new Integer(Token.t_namespace)); //$NON-NLS-1$
+ fgKeywords.put("new", new Integer(Token.t_new)); //$NON-NLS-1$
+ fgKeywords.put("not", new Integer(Token.t_not)); //$NON-NLS-1$
+ fgKeywords.put("not_eq", new Integer(Token.t_not_eq)); //$NON-NLS-1$
+ fgKeywords.put("operator", new Integer(Token.t_operator)); //$NON-NLS-1$
+ fgKeywords.put("or", new Integer(Token.t_or)); //$NON-NLS-1$
+ fgKeywords.put("or_eq", new Integer(Token.t_or_eq)); //$NON-NLS-1$
+ fgKeywords.put("private", new Integer(Token.t_private)); //$NON-NLS-1$
+ fgKeywords.put("protected", new Integer(Token.t_protected)); //$NON-NLS-1$
+ fgKeywords.put("public", new Integer(Token.t_public)); //$NON-NLS-1$
+ fgKeywords.put("register", new Integer(Token.t_register)); //$NON-NLS-1$
+ fgKeywords.put("reinterpret_cast", new Integer(Token.t_reinterpret_cast)); //$NON-NLS-1$
+ fgKeywords.put("return", new Integer(Token.t_return)); //$NON-NLS-1$
+ fgKeywords.put("short", new Integer(Token.t_short)); //$NON-NLS-1$
+ fgKeywords.put("signed", new Integer(Token.t_signed)); //$NON-NLS-1$
+ fgKeywords.put("sizeof", new Integer(Token.t_sizeof)); //$NON-NLS-1$
+ fgKeywords.put("static", new Integer(Token.t_static)); //$NON-NLS-1$
+ fgKeywords.put("static_cast", new Integer(Token.t_static_cast)); //$NON-NLS-1$
+ fgKeywords.put("struct", new Integer(Token.t_struct)); //$NON-NLS-1$
+ fgKeywords.put("switch", new Integer(Token.t_switch)); //$NON-NLS-1$
+ fgKeywords.put("template", new Integer(Token.t_template)); //$NON-NLS-1$
+ fgKeywords.put("this", new Integer(Token.t_this)); //$NON-NLS-1$
+ fgKeywords.put("throw", new Integer(Token.t_throw)); //$NON-NLS-1$
+ fgKeywords.put("true", new Integer(Token.t_true)); //$NON-NLS-1$
+ fgKeywords.put("try", new Integer(Token.t_try)); //$NON-NLS-1$
+ fgKeywords.put("typedef", new Integer(Token.t_typedef)); //$NON-NLS-1$
+ fgKeywords.put("typeid", new Integer(Token.t_typeid)); //$NON-NLS-1$
+ fgKeywords.put("typename", new Integer(Token.t_typename)); //$NON-NLS-1$
+ fgKeywords.put("union", new Integer(Token.t_union)); //$NON-NLS-1$
+ fgKeywords.put("unsigned", new Integer(Token.t_unsigned)); //$NON-NLS-1$
+ fgKeywords.put("using", new Integer(Token.t_using)); //$NON-NLS-1$
+ fgKeywords.put("virtual", new Integer(Token.t_virtual)); //$NON-NLS-1$
+ fgKeywords.put("void", new Integer(Token.t_void)); //$NON-NLS-1$
+ fgKeywords.put("volatile", new Integer(Token.t_volatile)); //$NON-NLS-1$
+ fgKeywords.put("wchar_t", new Integer(Token.t_wchar_t)); //$NON-NLS-1$
+ fgKeywords.put("while", new Integer(Token.t_while)); //$NON-NLS-1$
+ fgKeywords.put("xor", new Integer(Token.t_xor)); //$NON-NLS-1$
+ fgKeywords.put("xor_eq", new Integer(Token.t_xor_eq)); //$NON-NLS-1$
+
+ // additional java keywords
+ fgKeywords.put("abstract", new Integer(Token.t_abstract)); //$NON-NLS-1$
+ fgKeywords.put("boolean", new Integer(Token.t_boolean)); //$NON-NLS-1$
+ fgKeywords.put("byte", new Integer(Token.t_byte)); //$NON-NLS-1$
+ fgKeywords.put("extends", new Integer(Token.t_extends)); //$NON-NLS-1$
+ fgKeywords.put("final", new Integer(Token.t_final)); //$NON-NLS-1$
+ fgKeywords.put("finally", new Integer(Token.t_finally)); //$NON-NLS-1$
+ fgKeywords.put("implements", new Integer(Token.t_implements)); //$NON-NLS-1$
+ fgKeywords.put("import", new Integer(Token.t_import)); //$NON-NLS-1$
+ fgKeywords.put("interface", new Integer(Token.t_interface)); //$NON-NLS-1$
+ fgKeywords.put("instanceof", new Integer(Token.t_instanceof)); //$NON-NLS-1$
+ fgKeywords.put("native", new Integer(Token.t_native)); //$NON-NLS-1$
+ fgKeywords.put("null", new Integer(Token.t_null)); //$NON-NLS-1$
+ fgKeywords.put("package", new Integer(Token.t_package)); //$NON-NLS-1$
+ fgKeywords.put("super", new Integer(Token.t_super)); //$NON-NLS-1$
+ fgKeywords.put("synchronized", new Integer(Token.t_synchronized)); //$NON-NLS-1$
+ fgKeywords.put("throws", new Integer(Token.t_throws)); //$NON-NLS-1$
+ fgKeywords.put("transient", new Integer(Token.t_transient)); //$NON-NLS-1$
+ }
+} \ No newline at end of file
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/Token.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/Token.java
new file mode 100644
index 0000000000..fc3b7c6e89
--- /dev/null
+++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/Token.java
@@ -0,0 +1,509 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2010, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial implementation
+ * Anton Leherbauer - adding tokens for preprocessing directives
+ * Markus Schorn - classification of preprocessing directives.
+ * Red Hat Inc. - used in SystemTap editor
+ *******************************************************************************/
+package org.eclipse.linuxtools.internal.systemtap.ui.ide.editors.stp;
+
+public class Token {
+ public int type;
+ public String text;
+ public int offset;
+
+ public Token(int t, String i) {
+ type = t;
+ text = i;
+ }
+
+ public Token(int t, String i, ScannerContext context) {
+ set(t, i, context);
+ }
+
+ public void set(int t, String i, ScannerContext context) {
+ type = t;
+ text = i;
+ offset = context.getOffset() - text.length() - context.undoStackSize();
+ }
+
+ @Override
+ public String toString() {
+ return "Token type=" + type + " image =" + text + " offset=" + offset; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ }
+
+ public int getType() {
+ return type;
+ }
+
+ public String getText() {
+ return text;
+ }
+
+ public int getOffset() {
+ return offset;
+ }
+
+ public int getLength() {
+ return text.length();
+ }
+
+ public int getDelta(Token other) {
+ return other.getOffset() + other.getLength() - getOffset();
+ }
+
+ public boolean looksLikeExpressionStart() {
+ switch (type) {
+ case tINTEGER:
+ case t_false:
+ case t_true:
+ case tSTRING:
+ case tLSTRING:
+ case tFLOATINGPT:
+ case tCHAR:
+ case tAMPER:
+ case tDOT:
+ case tLPAREN:
+ return true;
+ default:
+ break;
+ }
+ return false;
+ }
+
+ public boolean looksLikeExpressionEnd() {
+ switch (type) {
+ case tINTEGER:
+ case tSTRING:
+ case tLSTRING:
+ case tFLOATINGPT:
+ case tCHAR:
+ case tRPAREN:
+ case tIDENTIFIER:
+ return true;
+ default:
+ break;
+ }
+ return false;
+ }
+
+ public boolean isPointer() {
+ return (type == tAMPER || type == tSTAR);
+ }
+
+ public boolean isOperator() {
+ switch (type) {
+ case t_new:
+ case t_delete:
+ case tPLUS:
+ case tMINUS:
+ case tSTAR:
+ case tDIV:
+ case tXOR:
+ case tMOD:
+ case tAMPER:
+ case tBITOR:
+ case tCOMPL:
+ case tNOT:
+ case tASSIGN:
+ case tLT:
+ case tGT:
+ case tPLUSASSIGN:
+ case tMINUSASSIGN:
+ case tSTARASSIGN:
+ case tDIVASSIGN:
+ case tMODASSIGN:
+ case tBITORASSIGN:
+ case tAMPERASSIGN:
+ case tXORASSIGN:
+ case tSHIFTL:
+ case tSHIFTR:
+ case tSHIFTLASSIGN:
+ case tSHIFTRASSIGN:
+ case tEQUAL:
+ case tNOTEQUAL:
+ case tLTEQUAL:
+ case tGTEQUAL:
+ case tAND:
+ case tOR:
+ case tINCR:
+ case tDECR:
+ case tCOMMA:
+ case tDOT:
+ case tDOTSTAR:
+ case tARROW:
+ case tARROWSTAR:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ public boolean isInfixOperator() {
+ switch (type) {
+ case tPLUS:
+ case tMINUS:
+ case tSTAR:
+ case tDIV:
+ case tXOR:
+ case tMOD:
+ case tAMPER:
+ case tBITOR:
+ case tASSIGN:
+ case tLT:
+ case tGT:
+ case tPLUSASSIGN:
+ case tMINUSASSIGN:
+ case tSTARASSIGN:
+ case tDIVASSIGN:
+ case tMODASSIGN:
+ case tBITORASSIGN:
+ case tAMPERASSIGN:
+ case tXORASSIGN:
+ case tSHIFTL:
+ case tSHIFTR:
+ case tSHIFTLASSIGN:
+ case tSHIFTRASSIGN:
+ case tEQUAL:
+ case tNOTEQUAL:
+ case tLTEQUAL:
+ case tGTEQUAL:
+ case tAND:
+ case tOR:
+ case tCOLON:
+ case tQUESTION:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ public boolean isPrefixOperator() {
+ switch (type) {
+ case tPLUS:
+ case tMINUS:
+ case tSTAR:
+ case tAMPER:
+ case tCOMPL:
+ case tNOT:
+ case tINCR:
+ case tDECR:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ public boolean isPostfixOperator() {
+ switch (type) {
+ case tINCR:
+ case tDECR:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ public boolean isAssignmentOperator() {
+ return isAssignmentOperator(type);
+ }
+
+ public static boolean isAssignmentOperator(int type) {
+ switch (type) {
+ case tASSIGN:
+ case tPLUSASSIGN:
+ case tMINUSASSIGN:
+ case tSTARASSIGN:
+ case tDIVASSIGN:
+ case tAMPERASSIGN:
+ case tBITORASSIGN:
+ case tXORASSIGN:
+ case tMODASSIGN:
+ case tSHIFTLASSIGN:
+ case tSHIFTRASSIGN:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ public boolean isControlStmt() {
+ switch (type) {
+ case t_if:
+ case t_else:
+ case t_for:
+ case t_do:
+ case t_while:
+ case t_switch:
+ case t_try:
+ case t_catch:
+ case t_finally:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ public boolean isWhiteSpace() {
+ return type == tWHITESPACE;
+ }
+
+ public boolean isComment() {
+ return isLineComment() || isBlockComment();
+ }
+
+ public boolean isLineComment() {
+ return type == tLINECOMMENT;
+ }
+
+ public boolean isBlockComment() {
+ return type == tBLOCKCOMMENT;
+ }
+
+ public boolean isCaseLabel() {
+ return type == t_case || type == t_default;
+ }
+
+ public boolean isStructType() {
+ return isStructType(type);
+ }
+
+ public static boolean isStructType(int type) {
+ return type == t_struct || type == t_union || type == t_class;
+ }
+
+ public boolean isVisibilityModifier() {
+ return isVisibilityModifier(type);
+ }
+
+ public static boolean isVisibilityModifier(int type) {
+ return type == t_public || type == t_protected || type == t_private;
+ }
+
+ public boolean isEndOfStatement() {
+ return type == tSEMI || type == tRBRACE;
+ }
+
+ public boolean isCPPToken() {
+ switch (type) {
+ case tCOLONCOLON:
+ case t_class:
+ case t_namespace:
+ case t_using:
+ case t_template:
+ case t_public:
+ case t_protected:
+ case t_private:
+ case t_operator:
+ case t_virtual:
+ case t_inline:
+ case t_friend:
+ case t_mutable:
+ case t_new:
+ case t_delete:
+ case t_reinterpret_cast:
+ case t_dynamic_cast:
+ case t_static_cast:
+ case t_finally:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ // overrider
+ public boolean isStringLiteral() {
+ return type == tSTRING || type == tLSTRING;
+ }
+
+ // overrider
+ public boolean isCharacterLiteral() {
+ return type == tCHAR;
+ }
+
+ // overrider
+ public boolean isPreprocessor() {
+ switch (type) {
+ case tPREPROCESSOR:
+ case tPREPROCESSOR_DEFINE:
+ case tPREPROCESSOR_INCLUDE:
+ return true;
+ }
+ return false;
+ }
+
+ // overrider
+ public boolean isIncludeDirective() {
+ return type == tPREPROCESSOR_INCLUDE;
+ }
+ // overrider
+ public boolean isMacroDefinition() {
+ return type == tPREPROCESSOR_DEFINE;
+ }
+
+ // Special Token types (non-grammar tokens)
+ public static final int tWHITESPACE = 1000;
+ public static final int tLINECOMMENT = 1001;
+ public static final int tBLOCKCOMMENT = 1002;
+ public static final int tPREPROCESSOR = 1003;
+ public static final int tPREPROCESSOR_INCLUDE = 1004;
+ public static final int tPREPROCESSOR_DEFINE = 1005;
+ public static final int tBADCHAR = 1006;
+
+ // Token types
+ static public final int tIDENTIFIER = 1;
+ static public final int tINTEGER = 2;
+ static public final int tCOLONCOLON = 3;
+ static public final int tCOLON = 4;
+ static public final int tSEMI = 5;
+ static public final int tCOMMA = 6;
+ static public final int tQUESTION = 7;
+ static public final int tLPAREN = 8;
+ static public final int tRPAREN = 9;
+ static public final int tLBRACKET = 10;
+ static public final int tRBRACKET = 11;
+ static public final int tLBRACE = 12;
+ static public final int tRBRACE = 13;
+ static public final int tPLUSASSIGN = 14;
+ static public final int tINCR = 15;
+ static public final int tPLUS = 16;
+ static public final int tMINUSASSIGN = 17;
+ static public final int tDECR = 18;
+ static public final int tARROWSTAR = 19;
+ static public final int tARROW = 20;
+ static public final int tMINUS = 21;
+ static public final int tSTARASSIGN = 22;
+ static public final int tSTAR = 23;
+ static public final int tMODASSIGN = 24;
+ static public final int tMOD = 25;
+ static public final int tXORASSIGN = 26;
+ static public final int tXOR = 27;
+ static public final int tAMPERASSIGN = 28;
+ static public final int tAND = 29;
+ static public final int tAMPER = 30;
+ static public final int tBITORASSIGN = 31;
+ static public final int tOR = 32;
+ static public final int tBITOR = 33;
+ static public final int tCOMPL = 34;
+ static public final int tNOTEQUAL = 35;
+ static public final int tNOT = 36;
+ static public final int tEQUAL = 37;
+ static public final int tASSIGN = 38;
+ static public final int tSHIFTL = 40;
+ static public final int tLTEQUAL = 41;
+ static public final int tLT = 42;
+ static public final int tSHIFTRASSIGN = 43;
+ static public final int tSHIFTR = 44;
+ static public final int tGTEQUAL = 45;
+ static public final int tGT = 46;
+ static public final int tSHIFTLASSIGN = 47;
+ static public final int tELIPSE = 48;
+ static public final int tDOTSTAR = 49;
+ static public final int tDOT = 50;
+ static public final int tDIVASSIGN = 51;
+ static public final int tDIV = 52;
+ static public final int tCLASSNAME = 53;
+ static public final int t_and = 54;
+ static public final int t_and_eq = 55;
+ static public final int t_asm = 56;
+ static public final int t_auto = 57;
+ static public final int t_bitand = 58;
+ static public final int t_bitor = 59;
+ static public final int t_bool = 60;
+ static public final int t_break = 61;
+ static public final int t_case = 62;
+ static public final int t_catch = 63;
+ static public final int t_char = 64;
+ static public final int t_class = 65;
+ static public final int t_compl = 66;
+ static public final int t_const = 67;
+ static public final int t_const_cast = 69;
+ static public final int t_continue = 70;
+ static public final int t_default = 71;
+ static public final int t_delete = 72;
+ static public final int t_do = 73;
+ static public final int t_double = 74;
+ static public final int t_dynamic_cast = 75;
+ static public final int t_else = 76;
+ static public final int t_enum = 77;
+ static public final int t_explicit = 78;
+ static public final int t_export = 79;
+ static public final int t_extern = 80;
+ static public final int t_false = 81;
+ static public final int t_float = 82;
+ static public final int t_for = 83;
+ static public final int t_friend = 84;
+ static public final int t_goto = 85;
+ static public final int t_if = 86;
+ static public final int t_inline = 87;
+ static public final int t_int = 88;
+ static public final int t_long = 89;
+ static public final int t_mutable = 90;
+ static public final int t_namespace = 91;
+ static public final int t_new = 92;
+ static public final int t_not = 93;
+ static public final int t_not_eq = 94;
+ static public final int t_operator = 95;
+ static public final int t_or = 96;
+ static public final int t_or_eq = 97;
+ static public final int t_private = 98;
+ static public final int t_protected = 99;
+ static public final int t_public = 100;
+ static public final int t_register = 101;
+ static public final int t_reinterpret_cast = 102;
+ static public final int t_return = 103;
+ static public final int t_short = 104;
+ static public final int t_sizeof = 105;
+ static public final int t_static = 106;
+ static public final int t_static_cast = 107;
+ static public final int t_signed = 108;
+ static public final int t_struct = 109;
+ static public final int t_switch = 110;
+ static public final int t_template = 111;
+ static public final int t_this = 112;
+ static public final int t_throw = 113;
+ static public final int t_true = 114;
+ static public final int t_try = 115;
+ static public final int t_typedef = 116;
+ static public final int t_typeid = 117;
+ static public final int t_typename = 118;
+ static public final int t_union = 119;
+ static public final int t_unsigned = 120;
+ static public final int t_using = 121;
+ static public final int t_virtual = 122;
+ static public final int t_void = 123;
+ static public final int t_volatile = 124;
+ static public final int t_wchar_t = 125;
+ static public final int t_while = 126;
+ static public final int t_xor = 127;
+ static public final int t_xor_eq = 128;
+ static public final int tSTRING = 129;
+ static public final int tFLOATINGPT = 130;
+ static public final int tLSTRING = 131;
+ static public final int tCHAR = 132;
+ static public final int tRSTRING = 133;
+ static public final int t_restrict = 136;
+ static public final int t_interface = 200;
+ static public final int t_import = 201;
+ static public final int t_instanceof = 202;
+ static public final int t_extends = 203;
+ static public final int t_implements = 204;
+ static public final int t_final = 205;
+ static public final int t_super = 206;
+ static public final int t_package = 207;
+ static public final int t_boolean = 208;
+ static public final int t_abstract = 209;
+ static public final int t_finally = 210;
+ static public final int t_null = 211;
+ static public final int t_synchronized = 212;
+ static public final int t_throws = 213;
+ static public final int t_byte = 214;
+ static public final int t_transient = 215;
+ static public final int t_native = 216;
+}

Back to the top