diff options
-rw-r--r-- | src/core/lombok/val.java | 29 | ||||
-rw-r--r-- | src/eclipseAgent/lombok/eclipse/agent/PatchVal.java | 35 | ||||
-rw-r--r-- | usage_examples/valExample_pre.jpage | 1 | ||||
-rw-r--r-- | website/features/val.html | 4 |
4 files changed, 64 insertions, 5 deletions
diff --git a/src/core/lombok/val.java b/src/core/lombok/val.java new file mode 100644 index 00000000..baab0f90 --- /dev/null +++ b/src/core/lombok/val.java @@ -0,0 +1,29 @@ +/* + * Copyright © 2010 Reinier Zwitserloot, Roel Spilker and Robbert Jan Grootjans. + * + * 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; + +/** + * Use {@code val} as the type of any local variable declaration (even in a for-each statement), and the type will be inferred from the initializing expression. + * For example: {@code val x = 10.0;} will infer {@code double}, and {@code val y = new ArrayList<String>();} will infer {@code ArrayList<String>}. The local variable + * will also be made final. + */ +public class val {} diff --git a/src/eclipseAgent/lombok/eclipse/agent/PatchVal.java b/src/eclipseAgent/lombok/eclipse/agent/PatchVal.java index b93fc4f1..b6523c3c 100644 --- a/src/eclipseAgent/lombok/eclipse/agent/PatchVal.java +++ b/src/eclipseAgent/lombok/eclipse/agent/PatchVal.java @@ -188,21 +188,47 @@ public class PatchVal { return expr.resolveType(scope); } + public static boolean matches(String key, char[] array) { + if (array == null || key.length() != array.length) return false; + for (int i = 0; i < array.length; i++) { + if (key.charAt(i) != array[i]) return false; + } + + return true; + } + public static boolean handleValForLocalDeclaration(LocalDeclaration local, BlockScope scope) { if (local == null || !LocalDeclaration.class.equals(local.getClass())) return false; boolean decomponent = false; + boolean isVal = false; + if (local.type instanceof SingleTypeReference) { char[] token = ((SingleTypeReference)local.type).token; - if (token == null || token.length != 3) return false; - else if (token[0] != 'v' || token[1] != 'a' || token[2] != 'l') return false; - } else return false; + if (matches("val", token)) isVal = true; + } + + if (local.type instanceof QualifiedTypeReference) { + char[][] tokens = ((QualifiedTypeReference)local.type).tokens; + if (tokens != null && tokens.length == 2 && matches("lombok", tokens[0]) && matches("val", tokens[1])) isVal = true; + } + + if (!isVal) return false; + + TypeBinding resolvedType = local.type.resolvedType; + if (resolvedType == null) resolvedType = local.type.resolveType(scope, false); + if (resolvedType == null) return false; + + char[] pkg = resolvedType.qualifiedPackageName(); + char[] nm = resolvedType.qualifiedSourceName(); + if (!matches("lombok", pkg) || !matches("val", nm)) return false; Expression init = local.initialization; if (init == null && Reflection.initCopyField != null) { try { init = (Expression) Reflection.initCopyField.get(local); } catch (Exception e) { + // init remains null. } } @@ -211,12 +237,11 @@ public class PatchVal { init = (Expression) Reflection.iterableCopyField.get(local); decomponent = true; } catch (Exception e) { + // init remains null. } } TypeReference replacement = null; - if (init != null && decomponent) { - } if (init != null) { TypeBinding resolved = decomponent ? getForEachComponentType(init, scope) : init.resolveType(scope); diff --git a/usage_examples/valExample_pre.jpage b/usage_examples/valExample_pre.jpage index 8b9dadc3..a621640f 100644 --- a/usage_examples/valExample_pre.jpage +++ b/usage_examples/valExample_pre.jpage @@ -1,5 +1,6 @@ import java.util.ArrayList; import java.util.HashMap; +import lombok.val; public class ValExample { public String example() { diff --git a/website/features/val.html b/website/features/val.html index a3ce58e0..4e05f8ca 100644 --- a/website/features/val.html +++ b/website/features/val.html @@ -19,6 +19,10 @@ the type will be inferred from the initializer expression. The local variable will also be made final. This feature works on local variables and on foreach loops only, not on fields. The initializer expression is required. </p><p> + <code>val</code> is actually a 'type' of sorts, and exists as a real class in the <code>lombok</code> package. You must import it for val to work (or use <code>lombok.val</code> as the type). + The existence of this type on a local variable declaration triggers both the adding of the <code>final</code> keyword as well as copying the type of the initializing expression which overwrites + the 'fake' <code>val</code> type. + </p><p> <em>WARNING: This feature does not currently work in NetBeans. We're working on fixing that.</em> </p> </div> |