Added 'val' as a type which the 'val' fake keyword must resolve to before val works,

as a gesture to make val less 'magical'. It even works, in eclipse. Next up: javac.
This commit is contained in:
Reinier Zwitserloot committed 2010-11-29 16:43:36 +01:00
1 parent 5e9b99bec8
commit 7dba9c850c
4 files changed
+64 -5

No files matched your search

+29
View File
@@ -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 {}
@@ -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);
+1
View File
@@ -1,5 +1,6 @@
import java.util.ArrayList;
import java.util.HashMap;
import lombok.val;
public class ValExample {
public String example() {
+4
View File
@@ -18,6 +18,10 @@
<em>NEW in Lombok 0.10: </em>You can use <code>val</code> as the type of a local variable declaration instead of actually writing the type. When you do this,
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>