aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorReinier Zwitserloot <reinier@zwitserloot.com>2013-11-19 23:12:16 +0100
committerReinier Zwitserloot <reinier@zwitserloot.com>2013-12-11 22:40:47 +0100
commit1723e21b5e5cb274080dafddaafb72e1aa9ae572 (patch)
tree42744432d164e27ce65815fb416c2be1b4eb1894
parent1025ffb8baa26a0a843318b3b5e70c717bb36c9a (diff)
downloadlombok-1723e21b5e5cb274080dafddaafb72e1aa9ae572.tar.gz
lombok-1723e21b5e5cb274080dafddaafb72e1aa9ae572.tar.bz2
lombok-1723e21b5e5cb274080dafddaafb72e1aa9ae572.zip
formatpreferences system v1
-rw-r--r--src/delombok/lombok/delombok/Delombok.java4
-rw-r--r--src/delombok/lombok/delombok/DelombokResult.java3
-rw-r--r--src/delombok/lombok/delombok/DocCommentIntegrator.java21
-rw-r--r--src/delombok/lombok/delombok/FormatPreferenceScanner.java165
-rw-r--r--src/delombok/lombok/delombok/FormatPreferences.java77
5 files changed, 269 insertions, 1 deletions
diff --git a/src/delombok/lombok/delombok/Delombok.java b/src/delombok/lombok/delombok/Delombok.java
index 0128e44f..fb376a4e 100644
--- a/src/delombok/lombok/delombok/Delombok.java
+++ b/src/delombok/lombok/delombok/Delombok.java
@@ -88,6 +88,10 @@ public class Delombok {
@Excludes("quiet")
private boolean verbose;
+ @Shorthand("f")
+ @Description("Sets formatting rules. Use 'help' or 'list' to list all available rules. Unset format rules are inferred by scanning the source for usages.")
+ private List<String> format = new ArrayList<String>();
+
@Shorthand("q")
@Description("No warnings or errors will be emitted to standard error")
@Excludes("verbose")
diff --git a/src/delombok/lombok/delombok/DelombokResult.java b/src/delombok/lombok/delombok/DelombokResult.java
index 6fd62bf6..866082d6 100644
--- a/src/delombok/lombok/delombok/DelombokResult.java
+++ b/src/delombok/lombok/delombok/DelombokResult.java
@@ -18,7 +18,8 @@
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
- */package lombok.delombok;
+ */
+package lombok.delombok;
import java.io.IOException;
import java.io.Writer;
diff --git a/src/delombok/lombok/delombok/DocCommentIntegrator.java b/src/delombok/lombok/delombok/DocCommentIntegrator.java
index 0955a003..c66ff0ec 100644
--- a/src/delombok/lombok/delombok/DocCommentIntegrator.java
+++ b/src/delombok/lombok/delombok/DocCommentIntegrator.java
@@ -1,3 +1,24 @@
+/*
+ * Copyright (C) 2009-2010 The Project Lombok Authors.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
package lombok.delombok;
import java.util.ArrayList;
diff --git a/src/delombok/lombok/delombok/FormatPreferenceScanner.java b/src/delombok/lombok/delombok/FormatPreferenceScanner.java
new file mode 100644
index 00000000..5c388a83
--- /dev/null
+++ b/src/delombok/lombok/delombok/FormatPreferenceScanner.java
@@ -0,0 +1,165 @@
+/*
+ * Copyright (C) 2013 The Project Lombok Authors.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+package lombok.delombok;
+
+import java.io.CharArrayReader;
+import java.io.IOException;
+import java.io.Reader;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Scans a java source file to figure out certain format preferences.
+ * Currently:<ul>
+ * <li>Indent style (tab or 2-8 spaces are supported). Default: tab</li>
+ * <li>Empty lines still carry the appropriate indent, vs. empty lines are empty. Default: empty</li>
+ */
+public class FormatPreferenceScanner {
+ /** Checks validity of preferences, and returns with a non-null value if ALL format keys are available, thus negating the need for a scan. */
+ private FormatPreferences tryEasy(Map<String, String> preferences) {
+ int count = 0;
+ for (Map.Entry<String, String> e : preferences.entrySet()) {
+ if (!FormatPreferences.KEYS.containsKey(e.getKey())) throw new IllegalArgumentException("Unknown format key: " + e.getKey());
+ if (!"scan".equalsIgnoreCase(e.getValue())) count++;
+ }
+ if (count >= FormatPreferences.KEYS.size()) return new FormatPreferences(preferences, "\t", false);
+ return null;
+ }
+
+ public FormatPreferences scan(Map<String, String> preferences, char[] source) {
+ FormatPreferences fps = tryEasy(preferences);
+ if (fps != null) return fps;
+
+ try {
+ return scan_(preferences, new CharArrayReader(source));
+ } catch (IOException e) {
+ throw new RuntimeException(e); //Can't happen; CAR doesn't throw these.
+ }
+ }
+
+ public FormatPreferences scan(Map<String, String> preferences, Reader in) throws IOException {
+ FormatPreferences fps = tryEasy(preferences);
+ if (fps != null) return fps;
+
+ return scan_(preferences, in);
+ }
+
+ private static FormatPreferences scan_(Map<String, String> preferences, Reader in) throws IOException {
+ int filledEmpties = 0;
+ List<String> indents = new ArrayList<String>();
+
+ char[] buffer = new char[32700];
+ int pos = 1;
+ int end = 0;
+
+ StringBuilder indentSoFar = new StringBuilder();
+ boolean inIndent = true;
+ boolean inComment = false;
+ char lastChar = ' ';
+
+ while (true) {
+ if (pos >= end) {
+ int r = in.read(buffer);
+ if (r == -1) break;
+ pos = 0;
+ end = r;
+ continue;
+ }
+
+ char c = buffer[pos++];
+ if (inComment) {
+ if (lastChar == '*' && c == '/') inComment = false;
+ lastChar = c;
+ continue;
+ }
+
+ if (lastChar == '/' && c == '*') {
+ inComment = true;
+ lastChar = ' ';
+ indentSoFar.setLength(0);
+ inIndent = false;
+ continue;
+ }
+
+ if (inIndent) {
+ boolean w = Character.isWhitespace(c);
+ if (c == '\n') {
+ if (indentSoFar.length() > 0 && indentSoFar.charAt(indentSoFar.length() -1) == '\r') {
+ indentSoFar.setLength(indentSoFar.length() - 1);
+ }
+
+ if (indentSoFar.length() > 0) {
+ filledEmpties++;
+ } else {
+ }
+ indents.add(indentSoFar.toString());
+ indentSoFar.setLength(0);
+ lastChar = c;
+ continue;
+ }
+
+ if (w) {
+ indentSoFar.append(c);
+ lastChar = c;
+ continue;
+ }
+
+ if (indentSoFar.length() > 0) {
+ indents.add(indentSoFar.toString());
+ indentSoFar.setLength(0);
+ }
+ lastChar = c;
+ inIndent = false;
+ continue;
+ }
+
+ lastChar = c;
+ if (c == '\n') {
+ inIndent = true;
+ indentSoFar.setLength(0);
+ }
+ }
+
+ String indent = null;
+ int lowestSpaceCount = Integer.MAX_VALUE;
+ for (String ind : indents) {
+ if (ind.indexOf('\t') > -1) {
+ indent = "\t";
+ break;
+ }
+ if (ind.length() < 2 || ind.length() > 8) continue;
+ if (ind.length() < lowestSpaceCount) lowestSpaceCount = ind.length();
+ }
+
+ if (lowestSpaceCount == Integer.MAX_VALUE) indent = "\t";
+
+ if (indent == null) {
+ char[] id = new char[lowestSpaceCount];
+ Arrays.fill(id, ' ');
+ indent = new String(id);
+ }
+
+ return new FormatPreferences(preferences, indent, filledEmpties > 0);
+ }
+}
diff --git a/src/delombok/lombok/delombok/FormatPreferences.java b/src/delombok/lombok/delombok/FormatPreferences.java
new file mode 100644
index 00000000..f4e6f143
--- /dev/null
+++ b/src/delombok/lombok/delombok/FormatPreferences.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2013 The Project Lombok Authors.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+package lombok.delombok;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+public final class FormatPreferences {
+ private final String indent;
+ private final boolean filledEmpties;
+ static final Map<String, String> KEYS;
+
+ static {
+ Map<String, String> keys = new LinkedHashMap<String, String>();
+ keys.put("indent", "The indent to use. 'tab' can be used to represent 1 tab. A number means that many spaces. Default: 'tab'");
+ keys.put("emptyLines", "Either 'indent' or 'blank'. indent means: Indent an empty line to the right level. Default: 'blank'");
+ KEYS = Collections.unmodifiableMap(keys);
+ }
+
+ public FormatPreferences(Map<String, String> preferences, String indent, boolean filledEmpties) {
+ if (preferences == null) preferences = Collections.emptyMap();
+
+ String indent_ = preferences.get("indent");
+ if (indent_ != null && !"scan".equalsIgnoreCase(indent_)) {
+ try {
+ int id = Integer.parseInt(indent_);
+ if (id > 0 && id < 32) {
+ char[] c = new char[id];
+ Arrays.fill(c, ' ');
+ indent_ = new String(c);
+ }
+ } catch (NumberFormatException ignore) {}
+ indent = indent_.replace("\\t", "\t").replace("tab", "\t");
+ }
+ String empties_ = preferences.get("emptyLines");
+ if ("indent".equalsIgnoreCase(empties_)) filledEmpties = true;
+ else if ("blank".equalsIgnoreCase(empties_)) filledEmpties = false;
+ else if (empties_ != null && !"scan".equalsIgnoreCase(empties_)) {
+ throw new IllegalArgumentException("Legal values for 'emptyLines' is scan, indent, or blank.");
+ }
+ this.indent = indent;
+ this.filledEmpties = filledEmpties;
+ }
+ public Map<String, String> getKeysAndDescriptions() {
+ return KEYS;
+ }
+
+ /** If true, empty lines should still be appropriately indented. If false, empty lines should be completely blank. */
+ public boolean fillEmpties() {
+ return filledEmpties;
+ }
+
+ public String indent() {
+ return indent;
+ }
+}