diff options
author | Jeff Johnston | 2013-07-05 15:47:47 +0000 |
---|---|---|
committer | Roland Grunberg | 2013-07-16 15:12:07 +0000 |
commit | eb89adf93e110820907276acac9ffb72b80aa8ee (patch) | |
tree | d4f8e0a4d72978c4d75c33bc98dbd92260938528 /systemtap | |
parent | cac6bb9eb77a7329e78b43161438475723075127 (diff) | |
download | org.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')
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 < str2 and 1 if str1 > 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 << 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: "<n>", 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: "<n>", 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: "<n>", 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: "<n>", 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: "<n>", 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: "<n>", 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: "<n>", 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: "<n>", 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: "<n>", 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: "<n>", 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: "<n>", 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: "<n>", 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: "<n>", 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: "<n>", 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: "<n>", 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: "<n>", 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: "<n>", 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: "<n>", 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 >= <code>position</code> + * and < <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> > <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 >= <code>position</code> + * and < <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> > <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 <= <code>position</code> + * and > <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> < <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> <= p < + * <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> > <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 >= <code>position</code> + * and < <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> > <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 >= <code>position</code> + * and < <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> > <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> < <code>p</code> <= <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> < <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 <= <code>position</code> + * and > <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> < <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 <= <code>position</code> + * and > <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> < <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<std::string>|(10) + * new str_vector |(10) + * new / * comment * / str_vector |(10) + * </pre> + * + * but not the following: + * + * <pre> + * new std::vector<std::string>(10)| + * new std::vector<std::string>|(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> < <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>-></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> < <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<T> { + * 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> < <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>&</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; +} |