mirror of
https://github.com/tiennm99/lombok.git
synced 2026-10-14 06:17:44 +00:00
Last massive documentation dump. All basic javadoc is now done, though especially the docs
on the lombok annotations in the lombok package need far more massaging. Also added a feature to HandleSynchronized to not auto-generate the locker fields if a specific name is provided (because, imagine you typoed those. You'd never find it!)
This commit is contained in:
1 parent
8d4c5369ee
commit
527b992a07
45 files changed
+1952
-54
No files matched your search
@@ -1,5 +1,29 @@
|
||||
/*
|
||||
* Copyright © 2009 Reinier Zwitserloot and Roel Spilker.
|
||||
*
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* Represents an AccessLevel. Used e.g. to specify the access level for generated methods and fields.
|
||||
*/
|
||||
public enum AccessLevel {
|
||||
PUBLIC, MODULE, PROTECTED, PACKAGE, PRIVATE;
|
||||
}
|
||||
@@ -1,3 +1,24 @@
|
||||
/*
|
||||
* Copyright © 2009 Reinier Zwitserloot and Roel Spilker.
|
||||
*
|
||||
* 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;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
@@ -5,8 +26,57 @@ import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Ensures the variable declaration that you annotate will be cleaned up by calling its close method, regardless
|
||||
* of what happens. Implemented by wrapping all statements following the local variable declaration to the
|
||||
* end of your scope into a try block that, as a finally action, closes the resource.
|
||||
*
|
||||
* Example:
|
||||
* <pre>
|
||||
* public void copyFile(String in, String out) throws IOException {
|
||||
* @Cleanup FileInputStream inStream = new FileInputStream(in);
|
||||
* @Cleamup FileOutputStream outStream = new FileOutputStream(out);
|
||||
* byte[] b = new byte[65536];
|
||||
* while (true) {
|
||||
* int r = inStream.read(b);
|
||||
* if (r == -1) break;
|
||||
* outStream.write(b, 0, r);
|
||||
* }
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* Will generate:
|
||||
* <pre>
|
||||
* public void copyFile(String in, String out) throws IOException {
|
||||
* @Cleanup FileInputStream inStream = new FileInputStream(in);
|
||||
* try {
|
||||
* @Cleamup FileOutputStream outStream = new FileOutputStream(out);
|
||||
* try {
|
||||
* byte[] b = new byte[65536];
|
||||
* while (true) {
|
||||
* int r = inStream.read(b);
|
||||
* if (r == -1) break;
|
||||
* outStream.write(b, 0, r);
|
||||
* }
|
||||
* } finally {
|
||||
* out.close();
|
||||
* }
|
||||
* } finally {
|
||||
* in.close();
|
||||
* }
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* Note that the final close method call, if it throws an exception, will overwrite any exception thrown
|
||||
* in the main body of the generated try block. You should NOT rely on this behaviour - future versions of
|
||||
* lombok intend to silently swallow any exception thrown by the cleanup method <i>_IF</i> the main body
|
||||
* throws an exception as well, as the earlier exception is usually far more useful.
|
||||
*
|
||||
* However, in java 1.6, generating the code to do this is prohibitively complicated.
|
||||
*/
|
||||
@Target(ElementType.LOCAL_VARIABLE)
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
public @interface Cleanup {
|
||||
/** The name of the method that cleans up the resource. By default, 'close'. The method must not have any parameters. */
|
||||
String cleanupMethod() default "close";
|
||||
}
|
||||
@@ -1,3 +1,24 @@
|
||||
/*
|
||||
* Copyright © 2009 Reinier Zwitserloot and Roel Spilker.
|
||||
*
|
||||
* 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;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
@@ -5,6 +26,18 @@ import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Generates getters for all fields, a useful toString method, and hashCode and equals implementations that check
|
||||
* all non-transient fields. Will also generate setters for all non-final fields, as well as a constructor.
|
||||
*
|
||||
* If any method to be generated already exists (in name - the return type or parameters are not relevant), then
|
||||
* that method will not be generated by the Data annotation.
|
||||
*
|
||||
* <code>toString</code>, <code>equals</code>, and <code>hashCode</code> use the deepX variants in the
|
||||
* <code>java.util.Arrays</code> utility class. Therefore, if your class has arrays that contain themselves,
|
||||
* these methods will just loop endlessly until the inevitable <code>StackOverflowError</code>. This behaviour
|
||||
* is no different from <code>java.util.ArrayList</code>, though.
|
||||
*/
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
public @interface Data {
|
||||
|
||||
@@ -1,3 +1,24 @@
|
||||
/*
|
||||
* Copyright © 2009 Reinier Zwitserloot and Roel Spilker.
|
||||
*
|
||||
* 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;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
@@ -5,8 +26,33 @@ import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Put on any field to make lombok build a standard getter.
|
||||
*
|
||||
* Example:
|
||||
* <pre>
|
||||
* private @Getter int foo;
|
||||
* </pre>
|
||||
*
|
||||
* will generate:
|
||||
*
|
||||
* <pre>
|
||||
* public int getFoo() {
|
||||
* return this.foo;
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* Note that fields of type <code>boolean</code> (but not <code>java.lang.Boolean</code>) will result in an
|
||||
* <code>isFoo</code> name instead of <code>getFoo</code>.
|
||||
*
|
||||
* If any method named <code>getFoo</code>/<code>isFoo</code> exists, regardless of return type or parameters, no method is generated,
|
||||
* and instead a compiler warning is emitted.
|
||||
*/
|
||||
@Target(ElementType.FIELD)
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
public @interface Getter {
|
||||
/**
|
||||
* If you want your setter to be non-public, you can specify an alternate access level here.
|
||||
*/
|
||||
lombok.AccessLevel value() default lombok.AccessLevel.PUBLIC;
|
||||
}
|
||||
@@ -1,5 +1,29 @@
|
||||
/*
|
||||
* Copyright © 2009 Reinier Zwitserloot and Roel Spilker.
|
||||
*
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* Useful utility methods to manipulate lombok-generated code.
|
||||
*/
|
||||
public class Lombok {
|
||||
/**
|
||||
* Throws any throwable 'sneakily' - you don't need to catch it, nor declare that you throw it onwards.
|
||||
@@ -15,6 +39,11 @@ public class Lombok {
|
||||
* about the concept of a 'checked exception'. All this method does is hide the act of throwing a checked exception
|
||||
* from the java compiler.
|
||||
*
|
||||
* Note that this method has a return type of <code>RuntimeException</code> it is advised you always call this
|
||||
* method as argument to the <code>throw</code> statement to avoid compiler errors regarding no return
|
||||
* statement and similar problems. This method won't of course return an actual <code>RuntimeException</code> -
|
||||
* it never returns, it always throws the provided exception.
|
||||
*
|
||||
* @param t The throwable to throw without requiring you to catch its type.
|
||||
* @return A dummy RuntimeException; this method never returns normally, it <em>always</em> throws an exception!
|
||||
*/
|
||||
|
||||
@@ -1,3 +1,24 @@
|
||||
/*
|
||||
* Copyright © 2009 Reinier Zwitserloot and Roel Spilker.
|
||||
*
|
||||
* 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;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
@@ -5,8 +26,30 @@ import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Put on any field to make lombok build a standard setter.
|
||||
*
|
||||
* Example:
|
||||
* <pre>
|
||||
* private @Setter int foo;
|
||||
* </pre>
|
||||
*
|
||||
* will generate:
|
||||
*
|
||||
* <pre>
|
||||
* public void setFoo(int foo) {
|
||||
* this.foo = foo;
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* If any method named <code>setFoo</code> exists, regardless of return type or parameters, no method is generated,
|
||||
* and instead a compiler warning is emitted.
|
||||
*/
|
||||
@Target(ElementType.FIELD)
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
public @interface Setter {
|
||||
/**
|
||||
* If you want your setter to be non-public, you can specify an alternate access level here.
|
||||
*/
|
||||
lombok.AccessLevel value() default lombok.AccessLevel.PUBLIC;
|
||||
}
|
||||
@@ -1,3 +1,24 @@
|
||||
/*
|
||||
* Copyright © 2009 Reinier Zwitserloot and Roel Spilker.
|
||||
*
|
||||
* 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;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
@@ -6,10 +27,42 @@ import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* DOCS: Requires lombok.jar at runtime.
|
||||
* Sneaky throw will avoid javac's insistence that you either catch or throw onward any checked exceptions that
|
||||
* statements in your method body declare they generate.
|
||||
*
|
||||
* Sneaky throw does not silently swallow, wrap into RuntimeException, or otherwise modify any exceptions of the listed
|
||||
* checked exception types. The JVM does not check for the consistency of the checked exception system; javac does,
|
||||
* and this annotation lets you opt out of its mechanism.
|
||||
*
|
||||
* You should use this annotation ONLY in the following two cases:<ol>
|
||||
* <li>You are certain the listed exception can't actually ever happen, or only in vanishingly rare situations.
|
||||
* You don't try to catch OutOfMemoryError on every statement either. Examples:<br>
|
||||
* <code>IOException</code> in <code>ByteArrayOutputStream</code><br>
|
||||
* <code>UnsupportedEncodingException</code> in new String(byteArray, "UTF-8").</li>
|
||||
* <li>You know for certain the caller can handle the exception (for example, because the caller is
|
||||
* an app manager that will handle all throwables that fall out of your method the same way), but due
|
||||
* to interface restrictions you can't just add these exceptions to your 'throws' clause.
|
||||
*
|
||||
* Note that, as SneakyThrow is an implementation detail and <i>NOT</i> part of your method signature, it is
|
||||
* a compile time error if none of the statements in your method body can throw a listed exception.
|
||||
*
|
||||
* <b><i>WARNING: </b></i>You must have lombok.jar available at the runtime of your app if you use SneakyThrows,
|
||||
* because your code is rewritten to use {@link Lombok.sneakyThrow(Throwable)}.
|
||||
*
|
||||
*
|
||||
* Example:
|
||||
* <pre>
|
||||
* @SneakyThrows(UnsupportedEncodingException.class)
|
||||
* public void utf8ToString(byte[] bytes) {
|
||||
* return new String(bytes, "UTF-8");
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* @see Lombok.sneakyThrow(Throwable)
|
||||
*/
|
||||
@Target({ElementType.METHOD, ElementType.CONSTRUCTOR})
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
public @interface SneakyThrows {
|
||||
/** The exception type(s) you want to sneakily throw onward. */
|
||||
Class<? extends Throwable>[] value();
|
||||
}
|
||||
@@ -1,3 +1,24 @@
|
||||
/*
|
||||
* Copyright © 2009 Reinier Zwitserloot and Roel Spilker.
|
||||
*
|
||||
* 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;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
@@ -5,8 +26,21 @@ import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Almost exactly like putting the 'synchronized' keyword on a method, except will synchronize on a private internal
|
||||
* Object, so that other code not under your control doesn't meddle with your thread management by locking on
|
||||
* your own instance.
|
||||
*
|
||||
* For non-static methods, a field named <code>$lock</code> is used, and for static methods,
|
||||
* <code>$LOCK</code> is used. These will be generated if needed and if they aren't already present. The contents
|
||||
* of the fields will be serializable.
|
||||
*/
|
||||
@Target(ElementType.METHOD)
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
public @interface Synchronized {
|
||||
/**
|
||||
* Optional: specify the name of a different field to lock on. It is a compile time error if this field
|
||||
* doesn't already exist (the fields are automatically generated only if you don't specify a specific name.
|
||||
*/
|
||||
String value() default "";
|
||||
}
|
||||
+173
-4
@@ -1,3 +1,24 @@
|
||||
/*
|
||||
* Copyright © 2009 Reinier Zwitserloot and Roel Spilker.
|
||||
*
|
||||
* 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.core;
|
||||
|
||||
import static lombok.Lombok.sneakyThrow;
|
||||
@@ -14,7 +35,15 @@ import java.util.IdentityHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Lombok wraps the AST produced by a target platform into its own AST system, mostly because both eclipse and javac
|
||||
* do not allow upward traversal (from a method to its owning type, for example).
|
||||
*
|
||||
* @param N The common type of all AST nodes in the internal representation of the target platform.
|
||||
* For example, JCTree for javac, and ASTNode for eclipse.
|
||||
*/
|
||||
public abstract class AST<N> {
|
||||
/** The kind of node represented by a given AST.Node object. */
|
||||
public enum Kind {
|
||||
COMPILATION_UNIT, TYPE, FIELD, INITIALIZER, METHOD, ANNOTATION, ARGUMENT, LOCAL, STATEMENT;
|
||||
}
|
||||
@@ -28,29 +57,52 @@ public abstract class AST<N> {
|
||||
this.fileName = fileName == null ? "(unknown).java" : fileName;
|
||||
}
|
||||
|
||||
/** Set the node object that wraps the internal Compilation Unit node. */
|
||||
protected void setTop(Node top) {
|
||||
this.top = top;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the content of the package declaration on this AST's top (Compilation Unit) node.
|
||||
*
|
||||
* Example: "java.util".
|
||||
*/
|
||||
public abstract String getPackageDeclaration();
|
||||
|
||||
/**
|
||||
* Return the contents of each non-static import statement on this AST's top (Compilation Unit) node.
|
||||
*
|
||||
* Example: "java.util.IOException".
|
||||
*/
|
||||
public abstract Collection<String> getImportStatements();
|
||||
|
||||
protected <T extends Node> T putInMap(T parent) {
|
||||
nodeMap.put(parent.get(), parent);
|
||||
identityDetector.put(parent.get(), null);
|
||||
return parent;
|
||||
/**
|
||||
* Puts the given node in the map so that javac/eclipse's own internal AST object can be translated to
|
||||
* an AST.Node object. Also registers the object as visited to avoid endless loops.
|
||||
*/
|
||||
protected <T extends Node> T putInMap(T node) {
|
||||
nodeMap.put(node.get(), node);
|
||||
identityDetector.put(node.get(), null);
|
||||
return node;
|
||||
}
|
||||
|
||||
/** Returns the node map, that can map javac/eclipse internal AST objects to AST.Node objects. */
|
||||
protected Map<N, Node> getNodeMap() {
|
||||
return nodeMap;
|
||||
}
|
||||
|
||||
/** Clears the registry that avoids endless loops, and empties the node map. The existing node map
|
||||
* object is left untouched, and instead a new map is created. */
|
||||
protected void clearState() {
|
||||
identityDetector = new IdentityHashMap<N, Void>();
|
||||
nodeMap = new IdentityHashMap<N, Node>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Marks the stated node as handled (to avoid endless loops if 2 nodes refer to each other, or a node
|
||||
* refers to itself). Will then return true if it was already set as handled before this call - in which
|
||||
* case you should do nothing lest the AST build process loops endlessly.
|
||||
*/
|
||||
protected boolean setAndGetAsHandled(N node) {
|
||||
if ( identityDetector.containsKey(node) ) return true;
|
||||
identityDetector.put(node, null);
|
||||
@@ -61,10 +113,12 @@ public abstract class AST<N> {
|
||||
return fileName;
|
||||
}
|
||||
|
||||
/** The AST.Node object representing the Compilation Unit. */
|
||||
public Node top() {
|
||||
return top;
|
||||
}
|
||||
|
||||
/** Maps a javac/eclipse internal AST Node to the appropriate AST.Node object. */
|
||||
public Node get(N node) {
|
||||
return nodeMap.get(node);
|
||||
}
|
||||
@@ -86,14 +140,33 @@ public abstract class AST<N> {
|
||||
return targetNode;
|
||||
}
|
||||
|
||||
/** An instance of this class wraps an eclipse/javac internal node object. */
|
||||
public abstract class Node {
|
||||
protected final Kind kind;
|
||||
protected final N node;
|
||||
protected final List<? extends Node> children;
|
||||
protected Node parent;
|
||||
|
||||
/** This flag has no specified meaning; you can set and retrieve it.
|
||||
*
|
||||
* In practice, for annotation nodes it means: Some AnnotationHandler finished whatever changes were required,
|
||||
* and for all other nodes it means: This node was made by a lombok operation.
|
||||
*/
|
||||
protected boolean handled;
|
||||
|
||||
/** structurally significant are those nodes that can be annotated in java 1.6 or are method-like toplevels,
|
||||
* so fields, local declarations, method arguments, methods, types, the Compilation Unit itself, and initializers. */
|
||||
protected boolean isStructurallySignificant;
|
||||
|
||||
/**
|
||||
* Creates a new Node object that represents the provided node.
|
||||
*
|
||||
* Make sure you manually set the parent correctly.
|
||||
*
|
||||
* @param node The AST object in the target parser's own internal AST tree that this node object will represent.
|
||||
* @param children A list of child nodes. Passing in null results in the children list being empty, not null.
|
||||
* @param kind The kind of node represented by this object.
|
||||
*/
|
||||
protected Node(N node, List<? extends Node> children, Kind kind) {
|
||||
this.kind = kind;
|
||||
this.node = node;
|
||||
@@ -102,29 +175,57 @@ public abstract class AST<N> {
|
||||
this.isStructurallySignificant = calculateIsStructurallySignificant();
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override public String toString() {
|
||||
return String.format("NODE %s (%s) %s%s",
|
||||
kind, node == null ? "(NULL)" : node.getClass(), handled ? "[HANDLED]" : "", node == null ? "" : node);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenient shortcut to the owning JavacAST object's getPackageDeclaration method.
|
||||
*
|
||||
* @see AST#getPackageDeclaration()
|
||||
*/
|
||||
public String getPackageDeclaration() {
|
||||
return AST.this.getPackageDeclaration();
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenient shortcut to the owning JavacAST object's getImportStatements method.
|
||||
*
|
||||
* @see AST#getImportStatements()
|
||||
*/
|
||||
public Collection<String> getImportStatements() {
|
||||
return AST.this.getImportStatements();
|
||||
}
|
||||
|
||||
/**
|
||||
* See {@link #isStructurallySignificant}.
|
||||
*/
|
||||
protected abstract boolean calculateIsStructurallySignificant();
|
||||
|
||||
/**
|
||||
* Convenient shortcut to the owning JavacAST object's getNodeFor method.
|
||||
*
|
||||
* @see AST#getNodeFor()
|
||||
*/
|
||||
public Node getNodeFor(N obj) {
|
||||
return AST.this.get(obj);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The javac/eclipse internal AST object wrapped by this AST.Node object.
|
||||
*/
|
||||
public N get() {
|
||||
return node;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces the AST node represented by this node object with the provided node. This node must
|
||||
* have a parent, obviously, for this to work.
|
||||
*
|
||||
* Also affects the underlying (eclipse/javac) AST.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public Node replaceWith(N newN, Kind kind) {
|
||||
Node newNode = buildTree(newN, kind);
|
||||
@@ -137,6 +238,11 @@ public abstract class AST<N> {
|
||||
return newNode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces the stated node with a new one. The old node must be a direct child of this node.
|
||||
*
|
||||
* Also affects the underlying (eclipse/javac) AST.
|
||||
*/
|
||||
public void replaceChildNode(N oldN, N newN) {
|
||||
replaceStatementInNode(get(), oldN, newN);
|
||||
}
|
||||
@@ -169,27 +275,58 @@ public abstract class AST<N> {
|
||||
return parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all children nodes.
|
||||
*
|
||||
* A copy is created, so changing the list has no effect. Also, while iterating through this list,
|
||||
* you may add, remove, or replace children without causing ConcurrentModificationExceptions.
|
||||
*/
|
||||
public Collection<? extends Node> down() {
|
||||
return new ArrayList<Node>(children);
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the value of the 'handled' flag.
|
||||
*
|
||||
* @see #handled
|
||||
*/
|
||||
public boolean isHandled() {
|
||||
return handled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the handled flag, then returns 'this'.
|
||||
*
|
||||
* @see #handled
|
||||
*/
|
||||
public Node setHandled() {
|
||||
this.handled = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenient shortcut to the owning JavacAST object's top method.
|
||||
*
|
||||
* @see AST#top()
|
||||
*/
|
||||
public Node top() {
|
||||
return top;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenient shortcut to the owning JavacAST object's getFileName method.
|
||||
*
|
||||
* @see AST#getFileName()
|
||||
*/
|
||||
public String getFileName() {
|
||||
return fileName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the stated node as a direct child of this node.
|
||||
*
|
||||
* Does not change the underlying (javac/eclipse) AST, only the wrapped view.
|
||||
*/
|
||||
@SuppressWarnings("unchecked") public Node add(N newChild, Kind kind) {
|
||||
Node n = buildTree(newChild, kind);
|
||||
if ( n == null ) return null;
|
||||
@@ -221,18 +358,30 @@ public abstract class AST<N> {
|
||||
nodeMap.remove(get());
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the stated node, which must be a direct child of this node, from the AST.
|
||||
*
|
||||
* Does not change the underlying (javac/eclipse) AST, only the wrapped view.
|
||||
*/
|
||||
public void removeChild(Node child) {
|
||||
children.remove(child);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the handled flag on this node, and all child nodes, then returns this.
|
||||
*
|
||||
* @see #handled
|
||||
*/
|
||||
public Node recursiveSetHandled() {
|
||||
this.handled = true;
|
||||
for ( Node child : children ) child.recursiveSetHandled();
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Generate a compiler error on this node. */
|
||||
public abstract void addError(String message);
|
||||
|
||||
/** Generate a compiler warning on this node. */
|
||||
public abstract void addWarning(String message);
|
||||
|
||||
/**
|
||||
@@ -245,10 +394,16 @@ public abstract class AST<N> {
|
||||
}
|
||||
}
|
||||
|
||||
/** Build an AST.Node object for the stated internal (javac/eclipse) AST Node object. */
|
||||
protected abstract Node buildTree(N item, Kind kind);
|
||||
|
||||
/**
|
||||
* Represents a field that contains AST children.
|
||||
*/
|
||||
protected static class FieldAccess {
|
||||
/** The actual field. */
|
||||
public final Field field;
|
||||
/** Dimensions of the field. Works for arrays, or for java.util.collections. */
|
||||
public final int dim;
|
||||
|
||||
FieldAccess(Field field, int dim) {
|
||||
@@ -258,6 +413,11 @@ public abstract class AST<N> {
|
||||
}
|
||||
|
||||
private static Map<Class<?>, Collection<FieldAccess>> fieldsOfASTClasses = new HashMap<Class<?>, Collection<FieldAccess>>();
|
||||
|
||||
/** Returns FieldAccess objects for the stated class. Each field that contains objects of the kind returned by
|
||||
* {@link #getStatementTypes()}, either directly or inside of an array or java.util.collection (or array-of-arrays,
|
||||
* or collection-of-collections, etcetera), is returned.
|
||||
*/
|
||||
protected Collection<FieldAccess> fieldsOf(Class<?> c) {
|
||||
Collection<FieldAccess> fields = fieldsOfASTClasses.get(c);
|
||||
if ( fields != null ) return fields;
|
||||
@@ -305,14 +465,23 @@ public abstract class AST<N> {
|
||||
} else return Object.class;
|
||||
}
|
||||
|
||||
/**
|
||||
* The supertypes which are considered AST Node children. Usually, the Statement, and the Expression,
|
||||
* though some platforms (such as eclipse) group these under one common supertype. */
|
||||
protected abstract Collection<Class<? extends N>> getStatementTypes();
|
||||
|
||||
/**
|
||||
* buildTree implementation that uses reflection to find all child nodes by way of inspecting
|
||||
* the fields. */
|
||||
protected <T extends Node> Collection<T> buildWithField(Class<T> nodeType, N statement, FieldAccess fa) {
|
||||
List<T> list = new ArrayList<T>();
|
||||
buildWithField0(nodeType, statement, fa, list);
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses reflection to find the given direct child on the given statement, and replace it with a new child.
|
||||
*/
|
||||
protected boolean replaceStatementInNode(N statement, N oldN, N newN) {
|
||||
for ( FieldAccess fa : fieldsOf(statement.getClass()) ) {
|
||||
if ( replaceStatementInField(fa, statement, oldN, newN) ) return true;
|
||||
|
||||
@@ -1,3 +1,24 @@
|
||||
/*
|
||||
* Copyright © 2009 Reinier Zwitserloot and Roel Spilker.
|
||||
*
|
||||
* 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.core;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
@@ -10,13 +31,23 @@ import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Represents a single annotation in a source file and can be used to query the parameters present on it.
|
||||
*/
|
||||
public class AnnotationValues<A extends Annotation> {
|
||||
private final Class<A> type;
|
||||
private final Map<String, AnnotationValue> values;
|
||||
private final AST<?>.Node ast;
|
||||
|
||||
|
||||
/**
|
||||
* Represents a single method on the annotation class. For example, the value() method on the Getter annotation.
|
||||
*/
|
||||
public static class AnnotationValue {
|
||||
/** A list of the raw expressions. List is size 1 unless an array is provided. */
|
||||
public final List<String> raws;
|
||||
|
||||
/** Guesses for each raw expression. If the raw expression is a literal expression, the guess will
|
||||
* likely be right. If not, it'll be wrong. */
|
||||
public final List<Object> valueGuesses;
|
||||
private final AST<?>.Node node;
|
||||
|
||||
@@ -33,7 +64,9 @@ public class AnnotationValues<A extends Annotation> {
|
||||
this.valueGuesses = Collections.singletonList(valueGuess);
|
||||
}
|
||||
|
||||
/** When the value is an array type. */
|
||||
/**
|
||||
* Like the other constructor, but used for when the annotation method is initialized with an array value.
|
||||
*/
|
||||
public AnnotationValue(AST<?>.Node node, List<String> raws, List<Object> valueGuesses) {
|
||||
this.node = node;
|
||||
this.raws = raws;
|
||||
@@ -52,21 +85,39 @@ public class AnnotationValues<A extends Annotation> {
|
||||
node.addError(message);
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override public String toString() {
|
||||
return "raws: " + raws + " valueGuesses: " + valueGuesses;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new AnnotationValues.
|
||||
*
|
||||
* @param type The annotation type. For example, "Getter.class"
|
||||
* @param values a Map of method names to AnnotationValue instances, for example 'value -> annotationValue instance'.
|
||||
* @param ast The Annotation node.
|
||||
*/
|
||||
public AnnotationValues(Class<A> type, Map<String, AnnotationValue> values, AST<?>.Node ast) {
|
||||
this.type = type;
|
||||
this.values = values;
|
||||
this.ast = ast;
|
||||
}
|
||||
|
||||
/**
|
||||
* Thrown on the fly if an actual annotation instance procured via the {@link #getInstance()} method is queried
|
||||
* for a method for which this AnnotationValues instance either doesn't have a guess or can't manage to fit
|
||||
* the guess into the required data type.
|
||||
*/
|
||||
public static class AnnotationValueDecodeFail extends RuntimeException {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/** The index into an array initializer (e.g. if the second value in an array initializer is
|
||||
* an integer constant expression like '5+SomeOtherClass.CONSTANT', this exception will be thrown,
|
||||
* and you'll get a '1' for idx. */
|
||||
public final int idx;
|
||||
|
||||
/** The AnnotationValue object that goes with the annotation method for which the failure occurred. */
|
||||
public final AnnotationValue owner;
|
||||
|
||||
public AnnotationValueDecodeFail(AnnotationValue owner, String msg, int idx) {
|
||||
@@ -83,8 +134,15 @@ public class AnnotationValues<A extends Annotation> {
|
||||
|
||||
private A cachedInstance = null;
|
||||
|
||||
/**
|
||||
* Creates an actual annotation instance. You can use this to query any annotation methods, except for
|
||||
* those annotation methods with class literals, as those can most likely not be turned into Class objects.
|
||||
*
|
||||
* If some of the methods cannot be implemented, this method still works; it's only when you call a method
|
||||
* that has a problematic value that an AnnotationValueDecodeFail exception occurs.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public A getInstance() throws AnnotationValueDecodeFail {
|
||||
public A getInstance() {
|
||||
if ( cachedInstance != null ) return cachedInstance;
|
||||
InvocationHandler invocations = new InvocationHandler() {
|
||||
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
|
||||
@@ -217,16 +275,32 @@ public class AnnotationValues<A extends Annotation> {
|
||||
"Can't translate a " + guess.getClass() + " to the expected " + expected, pos);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the raw expressions used for the provided annotationMethodName.
|
||||
*
|
||||
* You should use this method for annotation methods that return Class objects. Remember that
|
||||
* class literals end in ".class" which you probably want to strip off.
|
||||
*/
|
||||
public List<String> getRawExpressions(String annotationMethodName) {
|
||||
AnnotationValue v = values.get(annotationMethodName);
|
||||
return v == null ? Collections.<String>emptyList() : v.raws;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method to return the first result in a {@link getRawExpressions(String)} call.
|
||||
*
|
||||
* You should use this method if the annotation method is not an array type.
|
||||
*/
|
||||
public String getRawExpression(String annotationMethodName) {
|
||||
List<String> l = getRawExpressions(annotationMethodName);
|
||||
return l.isEmpty() ? null : l.get(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to translate class literals to their fully qualified names, such as 'Throwable.class' to 'java.lang.Throwable'.
|
||||
*
|
||||
* This process is at best a guess, but it will take into account import statements.
|
||||
*/
|
||||
public List<String> getProbableFQTypes(String annotationMethodName) {
|
||||
List<String> result = new ArrayList<String>();
|
||||
AnnotationValue v = values.get(annotationMethodName);
|
||||
@@ -236,6 +310,16 @@ public class AnnotationValues<A extends Annotation> {
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method to return the first result in a {@link getProbableFQType(String)} call.
|
||||
*
|
||||
* You should use this method if the annotation method is not an array type.
|
||||
*/
|
||||
public String getProbableFQType(String annotationMethodName) {
|
||||
List<String> l = getProbableFQTypes(annotationMethodName);
|
||||
return l.isEmpty() ? null : l.get(0);
|
||||
}
|
||||
|
||||
private String toFQ(String typeName) {
|
||||
Class<?> c;
|
||||
boolean fqn = typeName.indexOf('.') > -1;
|
||||
@@ -279,9 +363,4 @@ public class AnnotationValues<A extends Annotation> {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public String getProbableFQType(String annotationMethodName) {
|
||||
List<String> l = getProbableFQTypes(annotationMethodName);
|
||||
return l.isEmpty() ? null : l.get(0);
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,24 @@
|
||||
/*
|
||||
* Copyright © 2009 Reinier Zwitserloot and Roel Spilker.
|
||||
*
|
||||
* 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.core;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
@@ -5,14 +26,25 @@ import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Will print the tree structure of annotated node and all its children.
|
||||
*
|
||||
* This annotation is useful only for those working on Lombok, for example to test if a Lombok handlers is doing its
|
||||
* job correctly, or to see what the imagined endresult of a transformation is supposed to look like.
|
||||
*/
|
||||
@Target({ElementType.CONSTRUCTOR, ElementType.FIELD, ElementType.LOCAL_VARIABLE, ElementType.METHOD, ElementType.TYPE})
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
public @interface PrintAST {
|
||||
/**
|
||||
* Normally, the AST is printed to standard out, but you can pick a filename instead. Useful for many IDEs
|
||||
* which don't have a console unless you start them from the command line.
|
||||
*/
|
||||
String outfile() default "";
|
||||
|
||||
/**
|
||||
* Normally, the printer will print each node focusing on the node (E.g. classname, and such). By setting printContent to true,
|
||||
* methods, initializers, and other statement-containing elements actually print their java code instead of element class names.
|
||||
* Normally, the printer will print each node focusing on the node (E.g. classname, and such).
|
||||
* By setting printContent to true, methods, initializers, and other statement-containing elements
|
||||
* actually print their java code instead of a tree view of internal AST nodes.
|
||||
*/
|
||||
boolean printContent() default false;
|
||||
}
|
||||
@@ -1,3 +1,24 @@
|
||||
/*
|
||||
* Copyright © 2009 Reinier Zwitserloot and Roel Spilker.
|
||||
*
|
||||
* 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.core;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
@@ -16,13 +37,44 @@ import java.util.Set;
|
||||
|
||||
import lombok.Lombok;
|
||||
|
||||
/**
|
||||
* The java core libraries have a SPI discovery system, but it works only in Java 1.6 and up. For at least eclipse,
|
||||
* lombok actually works in java 1.5, so we've rolled our own SPI discovery system.
|
||||
*
|
||||
* It is not API compatible with <code>ServiceLoader</code>.
|
||||
*
|
||||
* @see java.util.ServiceLoader
|
||||
*/
|
||||
public class SpiLoadUtil {
|
||||
private SpiLoadUtil() {}
|
||||
private SpiLoadUtil() {
|
||||
//Prevent instantiation
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an iterator of instances that, at least according to the spi discovery file, are implementations
|
||||
* of the stated class.
|
||||
*
|
||||
* Like ServiceLoader, each listed class is turned into an instance by calling the public no-args constructor.
|
||||
*
|
||||
* Convenience method that calls the more elaborate {@link #findServices(Class, ClassLoader)} method with
|
||||
* this {@link java.lang.Thread}'s context class loader as <code>ClassLoader</code>.
|
||||
*
|
||||
* @param target class to find implementations for.
|
||||
*/
|
||||
public static <C> Iterator<C> findServices(Class<C> target) throws IOException {
|
||||
return findServices(target, Thread.currentThread().getContextClassLoader());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an iterator of class objects that, at least according to the spi discovery file, are implementations
|
||||
* of the stated class.
|
||||
*
|
||||
* Like ServiceLoader, each listed class is turned into an instance by calling the public no-args constructor.
|
||||
*
|
||||
* @param target class to find implementations for.
|
||||
* @param loader The classloader object to use to both the spi discovery files, as well as the loader to use
|
||||
* to make the returned instances.
|
||||
*/
|
||||
public static <C> Iterator<C> findServices(final Class<C> target, final ClassLoader loader) throws IOException {
|
||||
Enumeration<URL> resources = loader.getResources("META-INF/services/" + target.getName());
|
||||
final Set<String> entries = new LinkedHashSet<String>();
|
||||
@@ -70,6 +122,12 @@ public class SpiLoadUtil {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will find the <code>T</code> in <code>public class Foo extends BaseType<T>.
|
||||
*
|
||||
* It returns an annotation type because it is used exclusively to figure out which annotations are
|
||||
* being handled by {@link lombok.eclipse.EclipseAnnotationHandler} and {@link lombok.javac.JavacAnnotationHandler}.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static Class<? extends Annotation> findAnnotationClass(Class<?> c, Class<?> base) {
|
||||
if ( c == Object.class || c == null ) return null;
|
||||
|
||||
@@ -1,8 +1,50 @@
|
||||
/*
|
||||
* Copyright © 2009 Reinier Zwitserloot and Roel Spilker.
|
||||
*
|
||||
* 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.core;
|
||||
|
||||
/**
|
||||
* Container for static utility methods useful for some of the standard lombok transformations, regardless of
|
||||
* target platform (e.g. useful for both javac and eclipse lombok implementations).
|
||||
*/
|
||||
public class TransformationsUtil {
|
||||
private TransformationsUtil() {}
|
||||
private TransformationsUtil() {
|
||||
//Prevent instantiation
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a getter name from a given field name.
|
||||
*
|
||||
* Strategy:
|
||||
*
|
||||
* First, pick a prefix. 'get' normally, but 'is' if <code>isBoolean</code> is true.
|
||||
*
|
||||
* Then, check if the first character of the field is lowercase. If so, check if the second character
|
||||
* exists and is title or upper case. If so, uppercase the first character. If not, titlecase the first character.
|
||||
*
|
||||
* return the prefix plus the possibly title/uppercased first character, and the rest of the field name.
|
||||
*
|
||||
* @param fieldName the name of the field.
|
||||
* @param isBoolean if the field is of type 'boolean'. For fields of type 'java.lang.Boolean', you should provide <code>false</code>.
|
||||
*/
|
||||
public static String toGetterName(CharSequence fieldName, boolean isBoolean) {
|
||||
final String prefix = isBoolean ? "is" : "get";
|
||||
|
||||
@@ -11,16 +53,33 @@ public class TransformationsUtil {
|
||||
return buildName(prefix, fieldName.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a getter name from a given field name.
|
||||
*
|
||||
* Strategy:
|
||||
*
|
||||
* Check if the first character of the field is lowercase. If so, check if the second character
|
||||
* exists and is title or upper case. If so, uppercase the first character. If not, titlecase the first character.
|
||||
*
|
||||
* return "set" plus the possibly title/uppercased first character, and the rest of the field name.
|
||||
*
|
||||
* @param fieldName the name of the field.
|
||||
*/
|
||||
public static String toSetterName(CharSequence fieldName) {
|
||||
return buildName("set", fieldName.toString());
|
||||
}
|
||||
|
||||
private static String buildName(String prefix, String suffix) {
|
||||
if ( suffix.length() == 0 ) return prefix;
|
||||
|
||||
char first = suffix.charAt(0);
|
||||
if ( Character.isLowerCase(first) )
|
||||
suffix = String.format("%s%s", Character.toTitleCase(first), suffix.subSequence(1, suffix.length()));
|
||||
if ( Character.isLowerCase(first) ) {
|
||||
boolean useUpperCase = suffix.length() > 2 &&
|
||||
(Character.isTitleCase(suffix.charAt(1)) || Character.isUpperCase(suffix.charAt(1)));
|
||||
suffix = String.format("%s%s",
|
||||
useUpperCase ? Character.toUpperCase(first) : Character.toTitleCase(first),
|
||||
suffix.subSequence(1, suffix.length()));
|
||||
}
|
||||
return String.format("%s%s", prefix, suffix);
|
||||
}
|
||||
|
||||
public static String toSetterName(CharSequence fieldName) {
|
||||
return buildName("set", fieldName.toString());
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,24 @@
|
||||
/*
|
||||
* Copyright © 2009 Reinier Zwitserloot and Roel Spilker.
|
||||
*
|
||||
* 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.core;
|
||||
|
||||
import java.util.Collection;
|
||||
@@ -7,9 +28,23 @@ import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Library of types, which can be used to look up potential matching types.
|
||||
*
|
||||
* For example, if you put 'foo.Spork' and 'bar.Spork' into the library, and then ask for
|
||||
* all compatible types given the type 'Spork', you'll get both of them, but you'll only
|
||||
* get the one if you ask for compatible types given 'foo.Spork'.
|
||||
*
|
||||
* Useful to 'guess' if a given annotation AST node matches an annotation handler's target annotation.
|
||||
*/
|
||||
public class TypeLibrary {
|
||||
private final Map<String, Set<String>> simpleToQualifiedMap = new HashMap<String, Set<String>>();
|
||||
|
||||
/**
|
||||
* Add a type to the library.
|
||||
*
|
||||
* @param fullyQualifiedTypeName the FQN type name, such as 'java.lang.String'.
|
||||
*/
|
||||
public void addType(String fullyQualifiedTypeName) {
|
||||
int idx = fullyQualifiedTypeName.lastIndexOf('.');
|
||||
if ( idx == -1 ) throw new IllegalArgumentException(
|
||||
@@ -32,6 +67,11 @@ public class TypeLibrary {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all items in the type library that may be a match to the provided type.
|
||||
*
|
||||
* @param typeReference something like 'String' or even 'java.lang.String'.
|
||||
*/
|
||||
public Collection<String> findCompatible(String typeReference) {
|
||||
Set<String> result = simpleToQualifiedMap.get(typeReference);
|
||||
return result == null ? Collections.<String>emptySet() : result;
|
||||
|
||||
@@ -1,3 +1,24 @@
|
||||
/*
|
||||
* Copyright © 2009 Reinier Zwitserloot and Roel Spilker.
|
||||
*
|
||||
* 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.core;
|
||||
|
||||
import java.util.Collection;
|
||||
@@ -7,10 +28,17 @@ import java.util.Set;
|
||||
|
||||
import lombok.core.AST.Kind;
|
||||
|
||||
/**
|
||||
* Capable of resolving a simple type name such as 'String' into 'java.lang.String'.
|
||||
*/
|
||||
public class TypeResolver {
|
||||
private final TypeLibrary library;
|
||||
private Collection<String> imports;
|
||||
|
||||
/**
|
||||
* Creates a new TypeResolver that can be used to resolve types in a given library, encountered in
|
||||
* a source file with the provided package and import statements.
|
||||
*/
|
||||
public TypeResolver(TypeLibrary library, String packageString, Collection<String> importStrings) {
|
||||
this.library = library;
|
||||
this.imports = makeImportList(packageString, importStrings);
|
||||
@@ -23,6 +51,11 @@ public class TypeResolver {
|
||||
return imports;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds type matches for the stated type reference. The provided context is scanned for local type names
|
||||
* that shadow type names listed in import statements. If such a shadowing occurs, no matches are returned
|
||||
* for any shadowed types, as you would expect.
|
||||
*/
|
||||
public Collection<String> findTypeMatches(AST<?>.Node context, String typeRef) {
|
||||
Collection<String> potentialMatches = library.findCompatible(typeRef);
|
||||
if ( potentialMatches.isEmpty() ) return Collections.emptyList();
|
||||
|
||||
@@ -1,5 +1,29 @@
|
||||
/*
|
||||
* Copyright © 2009 Reinier Zwitserloot and Roel Spilker.
|
||||
*
|
||||
* 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.core;
|
||||
|
||||
/**
|
||||
* This class just holds lombok's current version.
|
||||
*/
|
||||
public class Version {
|
||||
private static final String VERSION = "0.4";
|
||||
|
||||
@@ -7,10 +31,16 @@ public class Version {
|
||||
//Prevent instantiation
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints the version followed by a newline, and exits.
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
System.out.println(VERSION);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current Lombok version.
|
||||
*/
|
||||
public static String getVersion() {
|
||||
return VERSION;
|
||||
}
|
||||
|
||||
@@ -1,3 +1,24 @@
|
||||
/*
|
||||
* Copyright © 2009 Reinier Zwitserloot and Roel Spilker.
|
||||
*
|
||||
* 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.eclipse;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
@@ -42,25 +63,43 @@ import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
|
||||
import org.osgi.framework.Bundle;
|
||||
|
||||
public class Eclipse {
|
||||
/**
|
||||
* Eclipse's Parser class is instrumented to not attempt to fill in the body of any method or initializer
|
||||
* or field initialization if this flag is set. Set it on the flag field of
|
||||
* any method, field, or initializer you create!
|
||||
*/
|
||||
public static final int ECLIPSE_DO_NOT_TOUCH_FLAG = ASTNode.Bit24;
|
||||
|
||||
private Eclipse() {
|
||||
//Prevent instantiation
|
||||
}
|
||||
|
||||
private static final String DEFAULT_BUNDLE = "org.eclipse.jdt.core";
|
||||
|
||||
/**
|
||||
* Generates an error in the eclipse error log. Note that most people never look at it!
|
||||
*/
|
||||
public static void error(CompilationUnitDeclaration cud, String message) {
|
||||
error(cud, message, DEFAULT_BUNDLE, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates an error in the eclipse error log. Note that most people never look at it!
|
||||
*/
|
||||
public static void error(CompilationUnitDeclaration cud, String message, Throwable error) {
|
||||
error(cud, message, DEFAULT_BUNDLE, error);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates an error in the eclipse error log. Note that most people never look at it!
|
||||
*/
|
||||
public static void error(CompilationUnitDeclaration cud, String message, String bundleName) {
|
||||
error(cud, message, bundleName, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates an error in the eclipse error log. Note that most people never look at it!
|
||||
*/
|
||||
public static void error(CompilationUnitDeclaration cud, String message, String bundleName, Throwable error) {
|
||||
Bundle bundle = Platform.getBundle(bundleName);
|
||||
if ( bundle == null ) {
|
||||
@@ -74,6 +113,10 @@ public class Eclipse {
|
||||
if ( cud != null ) EclipseAST.addProblemToCompilationResult(cud, false, message + " - See error log.", 0, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* For 'speed' reasons, eclipse works a lot with char arrays. I have my doubts this was a fruitful exercise,
|
||||
* but we need to deal with it. This turns [[java][lang][String]] into "java.lang.String".
|
||||
*/
|
||||
static String toQualifiedName(char[][] typeName) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
boolean first = true;
|
||||
@@ -84,6 +127,11 @@ public class Eclipse {
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* You can't share TypeParameter objects or bad things happen; for example, one 'T' resolves differently
|
||||
* from another 'T', even for the same T in a single class file. Unfortunately the TypeParameter type hierarchy
|
||||
* is complicated and there's no clone method on TypeParameter itself. This method can clone them.
|
||||
*/
|
||||
public static TypeParameter[] copyTypeParams(TypeParameter[] params) {
|
||||
if ( params == null ) return null;
|
||||
TypeParameter[] out = new TypeParameter[params.length];
|
||||
@@ -106,6 +154,10 @@ public class Eclipse {
|
||||
return out;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method that creates a new array and copies each TypeReference in the source array via
|
||||
* {@link #copyType(TypeReference)}.
|
||||
*/
|
||||
public static TypeReference[] copyTypes(TypeReference[] refs) {
|
||||
if ( refs == null ) return null;
|
||||
TypeReference[] outs = new TypeReference[refs.length];
|
||||
@@ -116,6 +168,11 @@ public class Eclipse {
|
||||
return outs;
|
||||
}
|
||||
|
||||
/**
|
||||
* You can't share TypeReference objects or subtle errors start happening.
|
||||
* Unfortunately the TypeReference type hierarchy is complicated and there's no clone
|
||||
* method on TypeReference itself. This method can clone them.
|
||||
*/
|
||||
public static TypeReference copyType(TypeReference ref) {
|
||||
if ( ref instanceof ParameterizedQualifiedTypeReference ) {
|
||||
ParameterizedQualifiedTypeReference iRef = (ParameterizedQualifiedTypeReference) ref;
|
||||
@@ -179,6 +236,11 @@ public class Eclipse {
|
||||
return ref;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the provided annotation type is likely to be the intended type for the given annotation node.
|
||||
*
|
||||
* This is a guess, but a decent one.
|
||||
*/
|
||||
public static boolean annotationTypeMatches(Class<? extends java.lang.annotation.Annotation> type, Node node) {
|
||||
if ( node.getKind() != Kind.ANNOTATION ) return false;
|
||||
TypeReference typeRef = ((Annotation)node.get()).type;
|
||||
@@ -197,6 +259,9 @@ public class Eclipse {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides AnnotationValues with the data it needs to do its thing.
|
||||
*/
|
||||
public static <A extends java.lang.annotation.Annotation> AnnotationValues<A>
|
||||
createAnnotation(Class<A> type, final Node annotationNode) {
|
||||
final Annotation annotation = (Annotation) annotationNode.get();
|
||||
|
||||
@@ -1,3 +1,24 @@
|
||||
/*
|
||||
* Copyright © 2009 Reinier Zwitserloot and Roel Spilker.
|
||||
*
|
||||
* 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.eclipse;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -25,13 +46,31 @@ import org.eclipse.jdt.internal.compiler.problem.DefaultProblem;
|
||||
import org.eclipse.jdt.internal.compiler.problem.ProblemSeverities;
|
||||
import org.eclipse.jdt.internal.compiler.util.Util;
|
||||
|
||||
/**
|
||||
* Wraps around eclipse's internal AST view to add useful features as well as the ability to visit parents from children,
|
||||
* something eclipse's own AST system does not offer.
|
||||
*/
|
||||
public class EclipseAST extends AST<ASTNode> {
|
||||
/**
|
||||
* Creates a new EclipseAST of the provided Compilation Unit.
|
||||
*
|
||||
* @param ast The compilation unit, which serves as the top level node in the tree to be built.
|
||||
*/
|
||||
public EclipseAST(CompilationUnitDeclaration ast) {
|
||||
super(toFileName(ast));
|
||||
this.compilationUnitDeclaration = ast;
|
||||
setTop(buildCompilationUnit(ast));
|
||||
this.completeParse = isComplete(ast);
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override public String getPackageDeclaration() {
|
||||
CompilationUnitDeclaration cud = (CompilationUnitDeclaration) top().get();
|
||||
ImportReference pkg = cud.currentPackage;
|
||||
return pkg == null ? null : Eclipse.toQualifiedName(pkg.getImportName());
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override public Collection<String> getImportStatements() {
|
||||
List<String> imports = new ArrayList<String>();
|
||||
CompilationUnitDeclaration cud = (CompilationUnitDeclaration) top().get();
|
||||
@@ -44,25 +83,38 @@ public class EclipseAST extends AST<ASTNode> {
|
||||
return imports;
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs through the entire AST, starting at the compilation unit, calling the provided visitor's visit methods
|
||||
* for each node, depth first.
|
||||
*/
|
||||
public void traverse(EclipseASTVisitor visitor) {
|
||||
top().traverse(visitor);
|
||||
}
|
||||
|
||||
void traverseChildren(EclipseASTVisitor visitor, Node node) {
|
||||
private void traverseChildren(EclipseASTVisitor visitor, Node node) {
|
||||
for ( Node child : node.down() ) {
|
||||
child.traverse(visitor);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Eclipse starts off with a 'diet' parse which leaves method bodies blank, amongst other shortcuts.
|
||||
*
|
||||
* For such diet parses, this method returns false, otherwise it returns true. Any lombok processor
|
||||
* that needs the contents of methods should just do nothing (and return false so it gets another shot later!)
|
||||
* when this is false.
|
||||
*/
|
||||
public boolean isCompleteParse() {
|
||||
return completeParse;
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override public Node top() {
|
||||
return (Node) super.top();
|
||||
}
|
||||
|
||||
public Node get(ASTNode node) {
|
||||
/** {@inheritDoc} */
|
||||
@Override public Node get(ASTNode node) {
|
||||
return (Node) super.get(node);
|
||||
}
|
||||
|
||||
@@ -72,7 +124,7 @@ public class EclipseAST extends AST<ASTNode> {
|
||||
final int sourceStart;
|
||||
final int sourceEnd;
|
||||
|
||||
public ParseProblem(boolean isWarning, String message, int sourceStart, int sourceEnd) {
|
||||
ParseProblem(boolean isWarning, String message, int sourceStart, int sourceEnd) {
|
||||
this.isWarning = isWarning;
|
||||
this.message = message;
|
||||
this.sourceStart = sourceStart;
|
||||
@@ -100,6 +152,10 @@ public class EclipseAST extends AST<ASTNode> {
|
||||
propagateProblems();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a problem to the provided CompilationResult object so that it will show up
|
||||
* in the Problems/Warnings view.
|
||||
*/
|
||||
static void addProblemToCompilationResult(CompilationUnitDeclaration ast,
|
||||
boolean isWarning, String message, int sourceStart, int sourceEnd) {
|
||||
if ( ast.compilationResult == null ) return;
|
||||
@@ -141,11 +197,20 @@ public class EclipseAST extends AST<ASTNode> {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Eclipse specific version of the AST.Node class.
|
||||
*/
|
||||
public final class Node extends AST<ASTNode>.Node {
|
||||
/**
|
||||
* See the {@link AST.Node} constructor for information.
|
||||
*/
|
||||
Node(ASTNode node, List<Node> children, Kind kind) {
|
||||
super(node, children, kind);
|
||||
}
|
||||
|
||||
/**
|
||||
* Visits this node and all child nodes depth-first, calling the provided visitor's visit methods.
|
||||
*/
|
||||
public void traverse(EclipseASTVisitor visitor) {
|
||||
switch ( getKind() ) {
|
||||
case COMPILATION_UNIT:
|
||||
@@ -219,6 +284,7 @@ public class EclipseAST extends AST<ASTNode> {
|
||||
}
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override public String getName() {
|
||||
final char[] n;
|
||||
if ( node instanceof TypeDeclaration ) n = ((TypeDeclaration)node).name;
|
||||
@@ -230,18 +296,22 @@ public class EclipseAST extends AST<ASTNode> {
|
||||
return n == null ? null : new String(n);
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override public void addError(String message) {
|
||||
this.addError(message, this.get().sourceStart, this.get().sourceEnd);
|
||||
}
|
||||
|
||||
/** Generate a compiler error that shows the wavy underline from-to the stated character positions. */
|
||||
public void addError(String message, int sourceStart, int sourceEnd) {
|
||||
addProblem(new ParseProblem(false, message, sourceStart, sourceEnd));
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override public void addWarning(String message) {
|
||||
this.addWarning(message, this.get().sourceStart, this.get().sourceEnd);
|
||||
}
|
||||
|
||||
/** Generate a compiler warning that shows the wavy underline from-to the stated character positions. */
|
||||
public void addWarning(String message, int sourceStart, int sourceEnd) {
|
||||
addProblem(new ParseProblem(true, message, sourceStart, sourceEnd));
|
||||
}
|
||||
@@ -251,6 +321,7 @@ public class EclipseAST extends AST<ASTNode> {
|
||||
return (Node) super.up();
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override protected boolean calculateIsStructurallySignificant() {
|
||||
if ( node instanceof TypeDeclaration ) return true;
|
||||
if ( node instanceof AbstractMethodDeclaration ) return true;
|
||||
@@ -281,6 +352,11 @@ public class EclipseAST extends AST<ASTNode> {
|
||||
return (Node) super.top();
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenient shortcut to the owning EclipseAST object's isCompleteParse method.
|
||||
*
|
||||
* @see JavacAST#isCompleteParse()
|
||||
*/
|
||||
public boolean isCompleteParse() {
|
||||
return completeParse;
|
||||
}
|
||||
@@ -289,17 +365,15 @@ public class EclipseAST extends AST<ASTNode> {
|
||||
private final CompilationUnitDeclaration compilationUnitDeclaration;
|
||||
private boolean completeParse;
|
||||
|
||||
public EclipseAST(CompilationUnitDeclaration ast) {
|
||||
super(toFileName(ast));
|
||||
this.compilationUnitDeclaration = ast;
|
||||
setTop(buildCompilationUnit(ast));
|
||||
this.completeParse = isComplete(ast);
|
||||
}
|
||||
|
||||
private static String toFileName(CompilationUnitDeclaration ast) {
|
||||
return ast.compilationResult.fileName == null ? null : new String(ast.compilationResult.fileName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Call to move an EclipseAST generated for a diet parse to rebuild itself for the full parse -
|
||||
* with filled in method bodies and such. Also propagates problems and errors, which in diet parse
|
||||
* mode can't be reliably added to the problems/warnings view.
|
||||
*/
|
||||
public void reparse() {
|
||||
propagateProblems();
|
||||
if ( completeParse ) return;
|
||||
@@ -315,6 +389,7 @@ public class EclipseAST extends AST<ASTNode> {
|
||||
return (unit.bits & ASTNode.HasAllMethodBodies) != 0;
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override protected Node buildTree(ASTNode node, Kind kind) {
|
||||
switch ( kind ) {
|
||||
case COMPILATION_UNIT:
|
||||
@@ -459,6 +534,8 @@ public class EclipseAST extends AST<ASTNode> {
|
||||
return putInMap(new Node(statement, childNodes, Kind.STATEMENT));
|
||||
}
|
||||
|
||||
/** For eclipse, only Statement counts, as Expression is a subclass of it, eventhough this isn't
|
||||
* entirely correct according to the JLS spec (only some expressions can be used as statements, not all of them). */
|
||||
@Override protected Collection<Class<? extends ASTNode>> getStatementTypes() {
|
||||
return Collections.<Class<? extends ASTNode>>singleton(Statement.class);
|
||||
}
|
||||
|
||||
@@ -1,3 +1,24 @@
|
||||
/*
|
||||
* Copyright © 2009 Reinier Zwitserloot and Roel Spilker.
|
||||
*
|
||||
* 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.eclipse;
|
||||
|
||||
import lombok.eclipse.EclipseAST.Node;
|
||||
@@ -12,26 +33,71 @@ import org.eclipse.jdt.internal.compiler.ast.LocalDeclaration;
|
||||
import org.eclipse.jdt.internal.compiler.ast.Statement;
|
||||
import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
|
||||
|
||||
/**
|
||||
* Standard adapter for the {@link EclipseASTVisitor} interface. Every method on that interface
|
||||
* has been implemented with an empty body. Override whichever methods you need.
|
||||
*/
|
||||
public abstract class EclipseASTAdapter implements EclipseASTVisitor {
|
||||
/** {@inheritDoc} */
|
||||
public void visitCompilationUnit(Node top, CompilationUnitDeclaration unit) {}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public void endVisitCompilationUnit(Node top, CompilationUnitDeclaration unit) {}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public void visitType(Node typeNode, TypeDeclaration type) {}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public void visitAnnotationOnType(TypeDeclaration type, Node annotationNode, Annotation annotation) {}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public void endVisitType(Node typeNode, TypeDeclaration type) {}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public void visitInitializer(Node initializerNode, Initializer initializer) {}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public void endVisitInitializer(Node initializerNode, Initializer initializer) {}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public void visitField(Node fieldNode, FieldDeclaration field) {}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public void visitAnnotationOnField(FieldDeclaration field, Node annotationNode, Annotation annotation) {}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public void endVisitField(Node fieldNode, FieldDeclaration field) {}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public void visitMethod(Node methodNode, AbstractMethodDeclaration method) {}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public void visitAnnotationOnMethod(AbstractMethodDeclaration method, Node annotationNode, Annotation annotation) {}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public void endVisitMethod(Node methodNode, AbstractMethodDeclaration method) {}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public void visitMethodArgument(Node argNode, Argument arg, AbstractMethodDeclaration method) {}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public void visitAnnotationOnMethodArgument(Argument arg, AbstractMethodDeclaration method, Node annotationNode, Annotation annotation) {}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public void endVisitMethodArgument(Node argNode, Argument arg, AbstractMethodDeclaration method) {}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public void visitLocal(Node localNode, LocalDeclaration local) {}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public void visitAnnotationOnLocal(LocalDeclaration local, Node annotationNode, Annotation annotation) {}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public void endVisitLocal(Node localNode, LocalDeclaration local) {}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public void visitStatement(Node statementNode, Statement statement) {}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public void endVisitStatement(Node statementNode, Statement statement) {}
|
||||
}
|
||||
@@ -1,7 +1,26 @@
|
||||
/*
|
||||
* Copyright © 2009 Reinier Zwitserloot and Roel Spilker.
|
||||
*
|
||||
* 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.eclipse;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.PrintStream;
|
||||
import java.lang.reflect.Modifier;
|
||||
|
||||
@@ -20,7 +39,10 @@ import org.eclipse.jdt.internal.compiler.ast.Statement;
|
||||
import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
|
||||
import org.eclipse.jdt.internal.compiler.ast.TypeReference;
|
||||
|
||||
//TODO expand javadoc
|
||||
/**
|
||||
* Implement so you can ask any JavacAST.Node to traverse depth-first through all children,
|
||||
* calling the appropriate visit and endVisit methods.
|
||||
*/
|
||||
public interface EclipseASTVisitor {
|
||||
/**
|
||||
* Called at the very beginning and end.
|
||||
@@ -82,20 +104,30 @@ public interface EclipseASTVisitor {
|
||||
void visitStatement(Node statementNode, Statement statement);
|
||||
void endVisitStatement(Node statementNode, Statement statement);
|
||||
|
||||
/**
|
||||
* Prints the structure of an AST.
|
||||
*/
|
||||
public static class Printer implements EclipseASTVisitor {
|
||||
private final PrintStream out;
|
||||
private final boolean printContent;
|
||||
private int disablePrinting = 0;
|
||||
private int indent = 0;
|
||||
|
||||
/**
|
||||
* @param printContent if true, method and initializer bodies are printed directly, as java code,
|
||||
* instead of a tree listing of every AST node inside it.
|
||||
*/
|
||||
public Printer(boolean printContent) {
|
||||
this(printContent, System.out);
|
||||
}
|
||||
|
||||
public Printer(boolean printContent, File file) throws FileNotFoundException {
|
||||
this(printContent, new PrintStream(file));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param printContent if true, method and initializer bodies are printed directly, as java code,
|
||||
* instead of a tree listing of every AST node inside it.
|
||||
* @param PrintStream write output to this stream. You must close it yourself. flush() is called after every line.
|
||||
*
|
||||
* @see java.io.PrintStream#flush()
|
||||
*/
|
||||
public Printer(boolean printContent, PrintStream out) {
|
||||
this.printContent = printContent;
|
||||
this.out = out;
|
||||
|
||||
@@ -1,7 +1,54 @@
|
||||
/*
|
||||
* Copyright © 2009 Reinier Zwitserloot and Roel Spilker.
|
||||
*
|
||||
* 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.eclipse;
|
||||
|
||||
import lombok.core.AnnotationValues;
|
||||
|
||||
/**
|
||||
* Implement this interface if you want to be triggered for a specific annotation.
|
||||
*
|
||||
* You MUST replace 'T' with a specific annotation type, such as:
|
||||
*
|
||||
* <code>public class HandleGetter implements EclipseAnnotationHandler<<b>Getter</b>></code>
|
||||
*
|
||||
* Because this generics parameter is inspected to figure out which class you're interested in.
|
||||
*
|
||||
* You also need to register yourself via SPI discovery as being an implementation of <code>EclipseAnnotationHandler</code>.
|
||||
*/
|
||||
public interface EclipseAnnotationHandler<T extends java.lang.annotation.Annotation> {
|
||||
/**
|
||||
* Called when an annotation is found that is likely to match the annotation you're interested in.
|
||||
*
|
||||
* Be aware that you'll be called for ANY annotation node in the source that looks like a match. There is,
|
||||
* for example, no guarantee that the annotation node belongs to a method, even if you set your
|
||||
* TargetType in the annotation to methods only.
|
||||
*
|
||||
* @param annotation The actual annotation - use this object to retrieve the annotation parameters.
|
||||
* @param ast The eclipse AST node representing the annotation.
|
||||
* @param annotationNode The Lombok AST wrapper around the 'ast' parameter. You can use this object
|
||||
* to travel back up the chain (something javac AST can't do) to the parent of the annotation, as well
|
||||
* as access useful methods such as generating warnings or errors focused on the annotation.
|
||||
* @return <code>true</code> if you don't want to be called again about this annotation during this
|
||||
* compile session (you've handled it), or <code>false</code> to indicate you aren't done yet.
|
||||
*/
|
||||
boolean handle(AnnotationValues<T> annotation, org.eclipse.jdt.internal.compiler.ast.Annotation ast, EclipseAST.Node annotationNode);
|
||||
}
|
||||
@@ -1,3 +1,24 @@
|
||||
/*
|
||||
* Copyright © 2009 Reinier Zwitserloot and Roel Spilker.
|
||||
*
|
||||
* 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.eclipse;
|
||||
|
||||
import static lombok.eclipse.Eclipse.toQualifiedName;
|
||||
@@ -21,7 +42,19 @@ import lombok.eclipse.EclipseAST.Node;
|
||||
import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
|
||||
import org.eclipse.jdt.internal.compiler.ast.TypeReference;
|
||||
|
||||
/**
|
||||
* This class tracks 'handlers' and knows how to invoke them for any given AST node.
|
||||
*
|
||||
* This class can find the handlers (via SPI discovery) and will set up the given AST node, such as
|
||||
* building an AnnotationValues instance.
|
||||
*/
|
||||
public class HandlerLibrary {
|
||||
/**
|
||||
* Creates a new HandlerLibrary. Errors will be reported to the eclipse Error log.
|
||||
* You probably want to use {@link #load()} instead.
|
||||
*/
|
||||
public HandlerLibrary() {}
|
||||
|
||||
private TypeLibrary typeLibrary = new TypeLibrary();
|
||||
|
||||
private static class AnnotationHandlerContainer<T extends Annotation> {
|
||||
@@ -47,6 +80,11 @@ public class HandlerLibrary {
|
||||
|
||||
private boolean skipPrintAST;
|
||||
|
||||
/**
|
||||
* Creates a new HandlerLibrary. Errors will be reported to the eclipse Error log.
|
||||
* then uses SPI discovery to load all annotation and visitor based handlers so that future calls
|
||||
* to the handle methods will defer to these handlers.
|
||||
*/
|
||||
public static HandlerLibrary load() {
|
||||
HandlerLibrary lib = new HandlerLibrary();
|
||||
|
||||
@@ -56,6 +94,7 @@ public class HandlerLibrary {
|
||||
return lib;
|
||||
}
|
||||
|
||||
/** Uses SPI Discovery to find implementations of {@link EclipseAnnotationHandler}. */
|
||||
@SuppressWarnings("unchecked") private static void loadAnnotationHandlers(HandlerLibrary lib) {
|
||||
Iterator<EclipseAnnotationHandler> it;
|
||||
try {
|
||||
@@ -80,6 +119,7 @@ public class HandlerLibrary {
|
||||
}
|
||||
}
|
||||
|
||||
/** Uses SPI Discovery to find implementations of {@link EclipseASTVisitor}. */
|
||||
private static void loadVisitorHandlers(HandlerLibrary lib) {
|
||||
Iterator<EclipseASTVisitor> it;
|
||||
try {
|
||||
@@ -96,6 +136,23 @@ public class HandlerLibrary {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the provided annotation node by first finding a qualifying instance of
|
||||
* {@link EclipseAnnotationHandler} and if one exists, calling it with a freshly cooked up
|
||||
* instance of {@link AnnotationValues}.
|
||||
*
|
||||
* Note that depending on the printASTOnly flag, the {@link lombok.core.PrintAST} annotation
|
||||
* will either be silently skipped, or everything that isn't <code>PrintAST</code> will be skipped.
|
||||
*
|
||||
* The HandlerLibrary will attempt to guess if the given annotation node represents a lombok annotation.
|
||||
* For example, if <code>lombok.*</code> is in the import list, then this method will guess that
|
||||
* <code>Getter</code> refers to <code>lombok.Getter</code>, presuming that {@link lombok.javac.handlers.HandleGetter}
|
||||
* has been loaded.
|
||||
*
|
||||
* @param unit The Compilation Unit that contains the Annotation AST Node.
|
||||
* @param node The Lombok AST Node representing the Annotation AST Node.
|
||||
* @param annotation 'node.get()' - convenience parameter.
|
||||
*/
|
||||
public boolean handle(CompilationUnitDeclaration ast, EclipseAST.Node annotationNode,
|
||||
org.eclipse.jdt.internal.compiler.ast.Annotation annotation) {
|
||||
String pkgName = annotationNode.getPackageDeclaration();
|
||||
@@ -124,6 +181,9 @@ public class HandlerLibrary {
|
||||
return handled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Will call all registered {@link EclipseASTVisitor} instances.
|
||||
*/
|
||||
public void callASTVisitors(EclipseAST ast) {
|
||||
for ( EclipseASTVisitor visitor : visitorHandlers ) try {
|
||||
ast.traverse(visitor);
|
||||
@@ -133,10 +193,18 @@ public class HandlerLibrary {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Lombok does not currently support triggering annotations in a specified order; the order is essentially
|
||||
* random right now. This lack of order is particularly annoying for the <code>PrintAST</code> annotation,
|
||||
* which is almost always intended to run last. Hence, this hack, which lets it in fact run last.
|
||||
*
|
||||
* {@see #skipAllButPrintAST}
|
||||
*/
|
||||
public void skipPrintAST() {
|
||||
skipPrintAST = true;
|
||||
}
|
||||
|
||||
/** {@see #skipPrintAST} */
|
||||
public void skipAllButPrintAST() {
|
||||
skipPrintAST = false;
|
||||
}
|
||||
|
||||
@@ -1,3 +1,24 @@
|
||||
/*
|
||||
* Copyright © 2009 Reinier Zwitserloot and Roel Spilker.
|
||||
*
|
||||
* 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.eclipse;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
@@ -102,6 +123,10 @@ public class TransformEclipseAST {
|
||||
this.ast = ast;
|
||||
}
|
||||
|
||||
/**
|
||||
* First handles all lombok annotations except PrintAST, then calls all non-annotation based handlers.
|
||||
* then handles any PrintASTs.
|
||||
*/
|
||||
public void go() {
|
||||
handlers.skipPrintAST();
|
||||
ast.traverse(new AnnotationVisitor());
|
||||
|
||||
@@ -1,3 +1,24 @@
|
||||
/*
|
||||
* Copyright © 2009 Reinier Zwitserloot and Roel Spilker.
|
||||
*
|
||||
* 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.eclipse.handlers;
|
||||
|
||||
import java.util.Arrays;
|
||||
@@ -24,6 +45,9 @@ import org.eclipse.jdt.internal.compiler.ast.SwitchStatement;
|
||||
import org.eclipse.jdt.internal.compiler.ast.TryStatement;
|
||||
import org.mangosdk.spi.ProviderFor;
|
||||
|
||||
/**
|
||||
* Handles the <code>lombok.Cleanup</code> annotation for javac.
|
||||
*/
|
||||
@ProviderFor(EclipseAnnotationHandler.class)
|
||||
public class HandleCleanup implements EclipseAnnotationHandler<Cleanup> {
|
||||
public boolean handle(AnnotationValues<Cleanup> annotation, Annotation ast, Node annotationNode) {
|
||||
|
||||
@@ -1,3 +1,24 @@
|
||||
/*
|
||||
* Copyright © 2009 Reinier Zwitserloot and Roel Spilker.
|
||||
*
|
||||
* 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.eclipse.handlers;
|
||||
|
||||
import static lombok.eclipse.Eclipse.*;
|
||||
@@ -67,6 +88,9 @@ import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
|
||||
import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
|
||||
import org.mangosdk.spi.ProviderFor;
|
||||
|
||||
/**
|
||||
* Handles the <code>lombok.Data</code> annotation for javac.
|
||||
*/
|
||||
@ProviderFor(EclipseAnnotationHandler.class)
|
||||
public class HandleData implements EclipseAnnotationHandler<Data> {
|
||||
public boolean handle(AnnotationValues<Data> annotation, Annotation ast, Node annotationNode) {
|
||||
|
||||
@@ -1,3 +1,24 @@
|
||||
/*
|
||||
* Copyright © 2009 Reinier Zwitserloot and Roel Spilker.
|
||||
*
|
||||
* 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.eclipse.handlers;
|
||||
|
||||
import static lombok.eclipse.handlers.PKG.*;
|
||||
@@ -23,8 +44,23 @@ import org.eclipse.jdt.internal.compiler.ast.TypeReference;
|
||||
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
|
||||
import org.mangosdk.spi.ProviderFor;
|
||||
|
||||
/**
|
||||
* Handles the <code>lombok.Getter</code> annotation for javac.
|
||||
*/
|
||||
@ProviderFor(EclipseAnnotationHandler.class)
|
||||
public class HandleGetter implements EclipseAnnotationHandler<Getter> {
|
||||
/**
|
||||
* Generates a getter on the stated field.
|
||||
*
|
||||
* Used by {@link HandleData}.
|
||||
*
|
||||
* The difference between this call and the handle method is as follows:
|
||||
*
|
||||
* If there is a <code>lombok.Getter</code> annotation on the field, it is used and the
|
||||
* same rules apply (e.g. warning if the method already exists, stated access level applies).
|
||||
* If not, the getter is still generated if it isn't already there, though there will not
|
||||
* be a warning if its already there. The default access level is used.
|
||||
*/
|
||||
public void generateGetterForField(Node fieldNode, ASTNode pos) {
|
||||
AccessLevel level = AccessLevel.PUBLIC;
|
||||
Node errorNode = fieldNode;
|
||||
|
||||
@@ -1,3 +1,24 @@
|
||||
/*
|
||||
* Copyright © 2009 Reinier Zwitserloot and Roel Spilker.
|
||||
*
|
||||
* 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.eclipse.handlers;
|
||||
|
||||
import java.io.File;
|
||||
@@ -14,6 +35,9 @@ import lombok.eclipse.EclipseASTVisitor;
|
||||
import lombok.eclipse.EclipseAnnotationHandler;
|
||||
import lombok.eclipse.EclipseAST.Node;
|
||||
|
||||
/**
|
||||
* Handles the <code>lombok.core.PrintAST</code> annotation for javac.
|
||||
*/
|
||||
@ProviderFor(EclipseAnnotationHandler.class)
|
||||
public class HandlePrintAST implements EclipseAnnotationHandler<PrintAST> {
|
||||
public boolean handle(AnnotationValues<PrintAST> annotation, Annotation ast, Node annotationNode) {
|
||||
|
||||
@@ -1,3 +1,24 @@
|
||||
/*
|
||||
* Copyright © 2009 Reinier Zwitserloot and Roel Spilker.
|
||||
*
|
||||
* 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.eclipse.handlers;
|
||||
|
||||
import static lombok.eclipse.handlers.PKG.*;
|
||||
@@ -27,8 +48,23 @@ import org.eclipse.jdt.internal.compiler.lookup.MethodScope;
|
||||
import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
|
||||
import org.mangosdk.spi.ProviderFor;
|
||||
|
||||
/**
|
||||
* Handles the <code>lombok.Setter</code> annotation for javac.
|
||||
*/
|
||||
@ProviderFor(EclipseAnnotationHandler.class)
|
||||
public class HandleSetter implements EclipseAnnotationHandler<Setter> {
|
||||
/**
|
||||
* Generates a setter on the stated field.
|
||||
*
|
||||
* Used by {@link HandleData}.
|
||||
*
|
||||
* The difference between this call and the handle method is as follows:
|
||||
*
|
||||
* If there is a <code>lombok.Setter</code> annotation on the field, it is used and the
|
||||
* same rules apply (e.g. warning if the method already exists, stated access level applies).
|
||||
* If not, the setter is still generated if it isn't already there, though there will not
|
||||
* be a warning if its already there. The default access level is used.
|
||||
*/
|
||||
public void generateSetterForField(Node fieldNode, ASTNode pos) {
|
||||
AccessLevel level = AccessLevel.PUBLIC;
|
||||
Node errorNode = fieldNode;
|
||||
|
||||
@@ -1,3 +1,24 @@
|
||||
/*
|
||||
* Copyright © 2009 Reinier Zwitserloot and Roel Spilker.
|
||||
*
|
||||
* 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.eclipse.handlers;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -27,6 +48,9 @@ import org.eclipse.jdt.internal.compiler.ast.TryStatement;
|
||||
import org.eclipse.jdt.internal.compiler.ast.TypeReference;
|
||||
import org.mangosdk.spi.ProviderFor;
|
||||
|
||||
/**
|
||||
* Handles the <code>lombok.HandleSneakyThrows</code> annotation for javac.
|
||||
*/
|
||||
@ProviderFor(EclipseAnnotationHandler.class)
|
||||
public class HandleSneakyThrows implements EclipseAnnotationHandler<SneakyThrows> {
|
||||
private static class DeclaredException {
|
||||
|
||||
@@ -1,3 +1,24 @@
|
||||
/*
|
||||
* Copyright © 2009 Reinier Zwitserloot and Roel Spilker.
|
||||
*
|
||||
* 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.eclipse.handlers;
|
||||
|
||||
import static lombok.eclipse.handlers.PKG.*;
|
||||
@@ -27,6 +48,9 @@ import org.eclipse.jdt.internal.compiler.ast.ThisReference;
|
||||
import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
|
||||
import org.mangosdk.spi.ProviderFor;
|
||||
|
||||
/**
|
||||
* Handles the <code>lombok.Synchronized</code> annotation for javac.
|
||||
*/
|
||||
@ProviderFor(EclipseAnnotationHandler.class)
|
||||
public class HandleSynchronized implements EclipseAnnotationHandler<Synchronized> {
|
||||
private static final char[] INSTANCE_LOCK_NAME = "$lock".toCharArray();
|
||||
@@ -49,9 +73,17 @@ public class HandleSynchronized implements EclipseAnnotationHandler<Synchronized
|
||||
}
|
||||
|
||||
char[] lockName = annotation.getInstance().value().toCharArray();
|
||||
if ( lockName.length == 0 ) lockName = method.isStatic() ? STATIC_LOCK_NAME : INSTANCE_LOCK_NAME;
|
||||
boolean autoMake = false;
|
||||
if ( lockName.length == 0 ) {
|
||||
autoMake = true;
|
||||
lockName = method.isStatic() ? STATIC_LOCK_NAME : INSTANCE_LOCK_NAME;
|
||||
}
|
||||
|
||||
if ( fieldExists(new String(lockName), methodNode) == MemberExistsResult.NOT_EXISTS ) {
|
||||
if ( !autoMake ) {
|
||||
annotationNode.addError("The field " + new String(lockName) + " does not exist.");
|
||||
return true;
|
||||
}
|
||||
FieldDeclaration fieldDecl = new FieldDeclaration(lockName, 0, -1);
|
||||
fieldDecl.declarationSourceEnd = -1;
|
||||
|
||||
|
||||
@@ -1,3 +1,24 @@
|
||||
/*
|
||||
* Copyright © 2009 Reinier Zwitserloot and Roel Spilker.
|
||||
*
|
||||
* 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.eclipse.handlers;
|
||||
|
||||
import java.lang.reflect.Modifier;
|
||||
|
||||
@@ -1,3 +1,24 @@
|
||||
/*
|
||||
* Copyright © 2009 Reinier Zwitserloot and Roel Spilker.
|
||||
*
|
||||
* 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.javac;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
@@ -30,6 +51,10 @@ import com.sun.tools.javac.util.Log;
|
||||
import com.sun.tools.javac.util.Name;
|
||||
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
|
||||
|
||||
/**
|
||||
* Wraps around javac's internal AST view to add useful features as well as the ability to visit parents from children,
|
||||
* something javac's own AST system does not offer.
|
||||
*/
|
||||
public class JavacAST extends AST<JCTree> {
|
||||
private final Messager messager;
|
||||
private final Name.Table nameTable;
|
||||
@@ -37,6 +62,14 @@ public class JavacAST extends AST<JCTree> {
|
||||
private final Symtab symtab;
|
||||
private final Log log;
|
||||
|
||||
/**
|
||||
* Creates a new JavacAST of the provided Compilation Unit.
|
||||
*
|
||||
* @param trees The trees instance to use to inspect the compilation unit. Generate via:
|
||||
* <code>Trees.getInstance(env)</code>
|
||||
* @param env The ProcessingEnvironment object passed e.g. to an annotation processor.
|
||||
* @param top The compilation unit, which serves as the top level node in the tree to be built.
|
||||
*/
|
||||
public JavacAST(Trees trees, JavacProcessingEnvironment env, JCCompilationUnit top) {
|
||||
super(top.sourcefile == null ? null : top.sourcefile.toString());
|
||||
setTop(buildCompilationUnit(top));
|
||||
@@ -47,11 +80,13 @@ public class JavacAST extends AST<JCTree> {
|
||||
this.symtab = Symtab.instance(env.getContext());
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override public String getPackageDeclaration() {
|
||||
JCCompilationUnit unit = (JCCompilationUnit)top().get();
|
||||
return unit.pid instanceof JCFieldAccess ? unit.pid.toString() : null;
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override public Collection<String> getImportStatements() {
|
||||
List<String> imports = new ArrayList<String>();
|
||||
JCCompilationUnit unit = (JCCompilationUnit)top().get();
|
||||
@@ -64,6 +99,10 @@ public class JavacAST extends AST<JCTree> {
|
||||
return imports;
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs through the entire AST, starting at the compilation unit, calling the provided visitor's visit methods
|
||||
* for each node, depth first.
|
||||
*/
|
||||
public void traverse(JavacASTVisitor visitor) {
|
||||
top().traverse(visitor);
|
||||
}
|
||||
@@ -74,26 +113,32 @@ public class JavacAST extends AST<JCTree> {
|
||||
}
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override public Node top() {
|
||||
return (Node) super.top();
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override public Node get(JCTree astNode) {
|
||||
return (Node) super.get(astNode);
|
||||
}
|
||||
|
||||
/** @return A Name object generated for the proper name table belonging to this AST. */
|
||||
public Name toName(String name) {
|
||||
return nameTable.fromString(name);
|
||||
}
|
||||
|
||||
/** @return A TreeMaker instance that you can use to create new AST nodes. */
|
||||
public TreeMaker getTreeMaker() {
|
||||
return treeMaker;
|
||||
}
|
||||
|
||||
/** @return The symbol table used by this AST for symbols. */
|
||||
public Symtab getSymbolTable() {
|
||||
return symtab;
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override protected Node buildTree(JCTree node, Kind kind) {
|
||||
switch ( kind ) {
|
||||
case COMPILATION_UNIT:
|
||||
@@ -214,6 +259,7 @@ public class JavacAST extends AST<JCTree> {
|
||||
return putInMap(new Node(statement, childNodes, Kind.STATEMENT));
|
||||
}
|
||||
|
||||
/** For javac, both JCExpression and JCStatement are considered as valid children types. */
|
||||
protected Collection<Class<? extends JCTree>> getStatementTypes() {
|
||||
Collection<Class<? extends JCTree>> collection = new ArrayList<Class<? extends JCTree>>(2);
|
||||
collection.add(JCStatement.class);
|
||||
@@ -225,11 +271,20 @@ public class JavacAST extends AST<JCTree> {
|
||||
if ( node != null ) nodes.add(node);
|
||||
}
|
||||
|
||||
/**
|
||||
* Javac specific version of the AST.Node class.
|
||||
*/
|
||||
public class Node extends AST<JCTree>.Node {
|
||||
/**
|
||||
* See the {@link AST.Node} constructor for information.
|
||||
*/
|
||||
public Node(JCTree node, List<Node> children, Kind kind) {
|
||||
super(node, children, kind);
|
||||
}
|
||||
|
||||
/**
|
||||
* Visits this node and all child nodes depth-first, calling the provided visitor's visit methods.
|
||||
*/
|
||||
public void traverse(JavacASTVisitor visitor) {
|
||||
switch ( this.getKind() ) {
|
||||
case COMPILATION_UNIT:
|
||||
@@ -301,6 +356,7 @@ public class JavacAST extends AST<JCTree> {
|
||||
}
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override public String getName() {
|
||||
final Name n;
|
||||
|
||||
@@ -312,6 +368,7 @@ public class JavacAST extends AST<JCTree> {
|
||||
return n == null ? null : n.toString();
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override protected boolean calculateIsStructurallySignificant() {
|
||||
if ( node instanceof JCClassDecl ) return true;
|
||||
if ( node instanceof JCMethodDecl ) return true;
|
||||
@@ -320,14 +377,29 @@ public class JavacAST extends AST<JCTree> {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenient shortcut to the owning JavacAST object's getTreeMaker method.
|
||||
*
|
||||
* @see JavacAST#getTreeMaker()
|
||||
*/
|
||||
public TreeMaker getTreeMaker() {
|
||||
return treeMaker;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenient shortcut to the owning JavacAST object's getSymbolTable method.
|
||||
*
|
||||
* @see JavacAST#getSymbolTable()
|
||||
*/
|
||||
public Symtab getSymbolTable() {
|
||||
return symtab;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenient shortcut to the owning JavacAST object's toName method.
|
||||
*
|
||||
* @see JavacAST#toName(String)
|
||||
*/
|
||||
public Name toName(String name) {
|
||||
return JavacAST.this.toName(name);
|
||||
}
|
||||
@@ -358,18 +430,30 @@ public class JavacAST extends AST<JCTree> {
|
||||
return (Collection<Node>) super.down();
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates an compiler error focused on the AST node represented by this node object.
|
||||
*/
|
||||
public void addError(String message) {
|
||||
printMessage(Diagnostic.Kind.ERROR, message, this, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates an compiler error focused on the AST node represented by this node object.
|
||||
*/
|
||||
public void addError(String message, DiagnosticPosition pos) {
|
||||
printMessage(Diagnostic.Kind.ERROR, message, null, pos);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a compiler warning focused on the AST node represented by this node object.
|
||||
*/
|
||||
public void addWarning(String message) {
|
||||
printMessage(Diagnostic.Kind.WARNING, message, this, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a compiler warning focused on the AST node represented by this node object.
|
||||
*/
|
||||
public void addWarning(String message, DiagnosticPosition pos) {
|
||||
printMessage(Diagnostic.Kind.WARNING, message, null, pos);
|
||||
}
|
||||
@@ -409,6 +493,7 @@ public class JavacAST extends AST<JCTree> {
|
||||
}
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override protected void setElementInASTCollection(Field field, Object refField, List<Collection<?>> chain, Collection<?> collection, int idx, JCTree newN) throws IllegalAccessException {
|
||||
com.sun.tools.javac.util.List<?> list = setElementInConsList(chain, collection, ((List)collection).get(idx), newN);
|
||||
@@ -439,7 +524,7 @@ public class JavacAST extends AST<JCTree> {
|
||||
if ( repl ) return com.sun.tools.javac.util.List.<Object>from(a);
|
||||
else return oldL;
|
||||
}
|
||||
|
||||
|
||||
private void increaseErrorCount(Messager messager) {
|
||||
try {
|
||||
Field f = messager.getClass().getDeclaredField("errorCount");
|
||||
|
||||
@@ -1,3 +1,24 @@
|
||||
/*
|
||||
* Copyright © 2009 Reinier Zwitserloot and Roel Spilker.
|
||||
*
|
||||
* 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.javac;
|
||||
|
||||
import lombok.javac.JavacAST.Node;
|
||||
@@ -10,26 +31,70 @@ import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
|
||||
import com.sun.tools.javac.tree.JCTree.JCMethodDecl;
|
||||
import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
|
||||
|
||||
/**
|
||||
* Standard adapter for the {@link JavacASTVisitor} interface. Every method on that interface
|
||||
* has been implemented with an empty body. Override whichever methods you need.
|
||||
*/
|
||||
public class JavacASTAdapter implements JavacASTVisitor {
|
||||
/** {@inheritDoc} */
|
||||
@Override public void visitCompilationUnit(Node top, JCCompilationUnit unit) {}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override public void endVisitCompilationUnit(Node top, JCCompilationUnit unit) {}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override public void visitType(Node typeNode, JCClassDecl type) {}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override public void visitAnnotationOnType(JCClassDecl type, Node annotationNode, JCAnnotation annotation) {}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override public void endVisitType(Node typeNode, JCClassDecl type) {}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override public void visitField(Node fieldNode, JCVariableDecl field) {}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override public void visitAnnotationOnField(JCVariableDecl field, Node annotationNode, JCAnnotation annotation) {}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override public void endVisitField(Node fieldNode, JCVariableDecl field) {}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override public void visitInitializer(Node initializerNode, JCBlock initializer) {}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override public void endVisitInitializer(Node initializerNode, JCBlock initializer) {}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override public void visitMethod(Node methodNode, JCMethodDecl method) {}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override public void visitAnnotationOnMethod(JCMethodDecl method, Node annotationNode, JCAnnotation annotation) {}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override public void endVisitMethod(Node methodNode, JCMethodDecl method) {}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override public void visitMethodArgument(Node argumentNode, JCVariableDecl argument, JCMethodDecl method) {}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override public void visitAnnotationOnMethodArgument(JCVariableDecl argument, JCMethodDecl method, Node annotationNode, JCAnnotation annotation) {}
|
||||
/** {@inheritDoc} */
|
||||
@Override public void endVisitMethodArgument(Node argumentNode, JCVariableDecl argument, JCMethodDecl method) {}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override public void visitLocal(Node localNode, JCVariableDecl local) {}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override public void visitAnnotationOnLocal(JCVariableDecl local, Node annotationNode, JCAnnotation annotation) {}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override public void endVisitLocal(Node localNode, JCVariableDecl local) {}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override public void visitStatement(Node statementNode, JCTree statement) {}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override public void endVisitStatement(Node statementNode, JCTree statement) {}
|
||||
}
|
||||
@@ -1,7 +1,26 @@
|
||||
/*
|
||||
* Copyright © 2009 Reinier Zwitserloot and Roel Spilker.
|
||||
*
|
||||
* 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.javac;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.PrintStream;
|
||||
|
||||
import lombok.javac.JavacAST.Node;
|
||||
@@ -15,6 +34,10 @@ import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
|
||||
import com.sun.tools.javac.tree.JCTree.JCMethodDecl;
|
||||
import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
|
||||
|
||||
/**
|
||||
* Implement so you can ask any JavacAST.Node to traverse depth-first through all children,
|
||||
* calling the appropriate visit and endVisit methods.
|
||||
*/
|
||||
public interface JavacASTVisitor {
|
||||
/**
|
||||
* Called at the very beginning and end.
|
||||
@@ -71,20 +94,30 @@ public interface JavacASTVisitor {
|
||||
void visitStatement(Node statementNode, JCTree statement);
|
||||
void endVisitStatement(Node statementNode, JCTree statement);
|
||||
|
||||
/**
|
||||
* Prints the structure of an AST.
|
||||
*/
|
||||
public static class Printer implements JavacASTVisitor {
|
||||
private final PrintStream out;
|
||||
private final boolean printContent;
|
||||
private int disablePrinting = 0;
|
||||
private int indent = 0;
|
||||
|
||||
/**
|
||||
* @param printContent if true, method and initializer bodies are printed directly, as java code,
|
||||
* instead of a tree listing of every AST node inside it.
|
||||
*/
|
||||
public Printer(boolean printContent) {
|
||||
this(printContent, System.out);
|
||||
}
|
||||
|
||||
public Printer(boolean printContent, File file) throws FileNotFoundException {
|
||||
this(printContent, new PrintStream(file));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param printContent if true, method and initializer bodies are printed directly, as java code,
|
||||
* instead of a tree listing of every AST node inside it.
|
||||
* @param PrintStream write output to this stream. You must close it yourself. flush() is called after every line.
|
||||
*
|
||||
* @see java.io.PrintStream#flush()
|
||||
*/
|
||||
public Printer(boolean printContent, PrintStream out) {
|
||||
this.printContent = printContent;
|
||||
this.out = out;
|
||||
|
||||
@@ -50,7 +50,7 @@ public interface JavacAnnotationHandler<T extends Annotation> {
|
||||
* @param ast The javac AST node representing the annotation.
|
||||
* @param annotationNode The Lombok AST wrapper around the 'ast' parameter. You can use this object
|
||||
* to travel back up the chain (something javac AST can't do) to the parent of the annotation, as well
|
||||
* as access useful methods such as generating warnings or errors focussed on the annotation.
|
||||
* as access useful methods such as generating warnings or errors focused on the annotation.
|
||||
* @return <code>true</code> if you don't want to be called again about this annotation during this
|
||||
* compile session (you've handled it), or <code>false</code> to indicate you aren't done yet.
|
||||
*/
|
||||
|
||||
@@ -66,6 +66,7 @@ public class Processor extends AbstractProcessor {
|
||||
private HandlerLibrary handlers;
|
||||
private Trees trees;
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override public void init(ProcessingEnvironment processingEnv) {
|
||||
super.init(processingEnv);
|
||||
if ( !(processingEnv instanceof JavacProcessingEnvironment) ) this.processingEnv = null;
|
||||
@@ -76,6 +77,7 @@ public class Processor extends AbstractProcessor {
|
||||
}
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
|
||||
if ( processingEnv == null ) return false;
|
||||
|
||||
|
||||
@@ -1,3 +1,24 @@
|
||||
/*
|
||||
* Copyright © 2009 Reinier Zwitserloot and Roel Spilker.
|
||||
*
|
||||
* 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.javac.handlers;
|
||||
|
||||
import lombok.Cleanup;
|
||||
@@ -26,6 +47,9 @@ import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
|
||||
import com.sun.tools.javac.util.List;
|
||||
import com.sun.tools.javac.util.Name;
|
||||
|
||||
/**
|
||||
* Handles the <code>lombok.Cleanup</code> annotation for javac.
|
||||
*/
|
||||
@ProviderFor(JavacAnnotationHandler.class)
|
||||
public class HandleCleanup implements JavacAnnotationHandler<Cleanup> {
|
||||
@Override public boolean handle(AnnotationValues<Cleanup> annotation, JCAnnotation ast, Node annotationNode) {
|
||||
|
||||
@@ -1,3 +1,24 @@
|
||||
/*
|
||||
* Copyright © 2009 Reinier Zwitserloot and Roel Spilker.
|
||||
*
|
||||
* 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.javac.handlers;
|
||||
|
||||
import java.lang.reflect.Modifier;
|
||||
@@ -37,6 +58,9 @@ import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
|
||||
import com.sun.tools.javac.util.List;
|
||||
import com.sun.tools.javac.util.Name;
|
||||
|
||||
/**
|
||||
* Handles the <code>lombok.Data</code> annotation for javac.
|
||||
*/
|
||||
@ProviderFor(JavacAnnotationHandler.class)
|
||||
public class HandleData implements JavacAnnotationHandler<Data> {
|
||||
@Override public boolean handle(AnnotationValues<Data> annotation, JCAnnotation ast, Node annotationNode) {
|
||||
|
||||
@@ -1,3 +1,24 @@
|
||||
/*
|
||||
* Copyright © 2009 Reinier Zwitserloot and Roel Spilker.
|
||||
*
|
||||
* 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.javac.handlers;
|
||||
|
||||
import static lombok.javac.handlers.PKG.*;
|
||||
@@ -24,8 +45,23 @@ import com.sun.tools.javac.util.List;
|
||||
import com.sun.tools.javac.util.Name;
|
||||
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
|
||||
|
||||
/**
|
||||
* Handles the <code>lombok.Getter</code> annotation for javac.
|
||||
*/
|
||||
@ProviderFor(JavacAnnotationHandler.class)
|
||||
public class HandleGetter implements JavacAnnotationHandler<Getter> {
|
||||
/**
|
||||
* Generates a getter on the stated field.
|
||||
*
|
||||
* Used by {@link HandleData}.
|
||||
*
|
||||
* The difference between this call and the handle method is as follows:
|
||||
*
|
||||
* If there is a <code>lombok.Getter</code> annotation on the field, it is used and the
|
||||
* same rules apply (e.g. warning if the method already exists, stated access level applies).
|
||||
* If not, the getter is still generated if it isn't already there, though there will not
|
||||
* be a warning if its already there. The default access level is used.
|
||||
*/
|
||||
public void generateGetterForField(Node fieldNode, DiagnosticPosition pos) {
|
||||
AccessLevel level = AccessLevel.PUBLIC;
|
||||
Node errorNode = fieldNode;
|
||||
|
||||
@@ -1,3 +1,24 @@
|
||||
/*
|
||||
* Copyright © 2009 Reinier Zwitserloot and Roel Spilker.
|
||||
*
|
||||
* 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.javac.handlers;
|
||||
|
||||
import java.io.File;
|
||||
@@ -15,6 +36,9 @@ import lombok.javac.JavacASTVisitor;
|
||||
import lombok.javac.JavacAnnotationHandler;
|
||||
import lombok.javac.JavacAST.Node;
|
||||
|
||||
/**
|
||||
* Handles the <code>lombok.core.PrintAST</code> annotation for javac.
|
||||
*/
|
||||
@ProviderFor(JavacAnnotationHandler.class)
|
||||
public class HandlePrintAST implements JavacAnnotationHandler<PrintAST> {
|
||||
@Override public boolean handle(AnnotationValues<PrintAST> annotation, JCAnnotation ast, Node annotationNode) {
|
||||
|
||||
@@ -1,3 +1,24 @@
|
||||
/*
|
||||
* Copyright © 2009 Reinier Zwitserloot and Roel Spilker.
|
||||
*
|
||||
* 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.javac.handlers;
|
||||
|
||||
import static lombok.javac.handlers.PKG.*;
|
||||
@@ -27,8 +48,23 @@ import com.sun.tools.javac.util.List;
|
||||
import com.sun.tools.javac.util.Name;
|
||||
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
|
||||
|
||||
/**
|
||||
* Handles the <code>lombok.Setter</code> annotation for javac.
|
||||
*/
|
||||
@ProviderFor(JavacAnnotationHandler.class)
|
||||
public class HandleSetter implements JavacAnnotationHandler<Setter> {
|
||||
/**
|
||||
* Generates a setter on the stated field.
|
||||
*
|
||||
* Used by {@link HandleData}.
|
||||
*
|
||||
* The difference between this call and the handle method is as follows:
|
||||
*
|
||||
* If there is a <code>lombok.Setter</code> annotation on the field, it is used and the
|
||||
* same rules apply (e.g. warning if the method already exists, stated access level applies).
|
||||
* If not, the setter is still generated if it isn't already there, though there will not
|
||||
* be a warning if its already there. The default access level is used.
|
||||
*/
|
||||
public void generateSetterForField(Node fieldNode, DiagnosticPosition pos) {
|
||||
AccessLevel level = AccessLevel.PUBLIC;
|
||||
Node errorNode = fieldNode;
|
||||
|
||||
@@ -1,3 +1,24 @@
|
||||
/*
|
||||
* Copyright © 2009 Reinier Zwitserloot and Roel Spilker.
|
||||
*
|
||||
* 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.javac.handlers;
|
||||
|
||||
import static lombok.javac.handlers.PKG.chainDots;
|
||||
@@ -24,6 +45,9 @@ import com.sun.tools.javac.tree.JCTree.JCStatement;
|
||||
import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
|
||||
import com.sun.tools.javac.util.List;
|
||||
|
||||
/**
|
||||
* Handles the <code>lombok.SneakyThrows</code> annotation for javac.
|
||||
*/
|
||||
@ProviderFor(JavacAnnotationHandler.class)
|
||||
public class HandleSneakyThrows implements JavacAnnotationHandler<SneakyThrows> {
|
||||
@Override public boolean handle(AnnotationValues<SneakyThrows> annotation, JCAnnotation ast, Node annotationNode) {
|
||||
|
||||
@@ -1,3 +1,24 @@
|
||||
/*
|
||||
* Copyright © 2009 Reinier Zwitserloot and Roel Spilker.
|
||||
*
|
||||
* 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.javac.handlers;
|
||||
|
||||
import static lombok.javac.handlers.PKG.*;
|
||||
@@ -21,6 +42,9 @@ import lombok.core.AST.Kind;
|
||||
import lombok.javac.JavacAnnotationHandler;
|
||||
import lombok.javac.JavacAST.Node;
|
||||
|
||||
/**
|
||||
* Handles the <code>lombok.Synchronized</code> annotation for javac.
|
||||
*/
|
||||
@ProviderFor(JavacAnnotationHandler.class)
|
||||
public class HandleSynchronized implements JavacAnnotationHandler<Synchronized> {
|
||||
private static final String INSTANCE_LOCK_NAME = "$lock";
|
||||
@@ -42,11 +66,19 @@ public class HandleSynchronized implements JavacAnnotationHandler<Synchronized>
|
||||
}
|
||||
boolean isStatic = (method.mods.flags & Flags.STATIC) != 0;
|
||||
String lockName = annotation.getInstance().value();
|
||||
if ( lockName.length() == 0 ) lockName = isStatic ? STATIC_LOCK_NAME : INSTANCE_LOCK_NAME;
|
||||
boolean autoMake = false;
|
||||
if ( lockName.length() == 0 ) {
|
||||
autoMake = true;
|
||||
lockName = isStatic ? STATIC_LOCK_NAME : INSTANCE_LOCK_NAME;
|
||||
}
|
||||
|
||||
TreeMaker maker = methodNode.getTreeMaker();
|
||||
|
||||
if ( fieldExists(lockName, methodNode) == MemberExistsResult.NOT_EXISTS ) {
|
||||
if ( !autoMake ) {
|
||||
annotationNode.addError("The field " + new String(lockName) + " does not exist.");
|
||||
return true;
|
||||
}
|
||||
JCExpression objectType = chainDots(maker, methodNode, "java", "lang", "Object");
|
||||
//We use 'new Object[0];' because quite unlike 'new Object();', empty arrays *ARE* serializable!
|
||||
JCNewArray newObjectArray = maker.NewArray(chainDots(maker, methodNode, "java", "lang", "Object"),
|
||||
|
||||
@@ -1,3 +1,24 @@
|
||||
/*
|
||||
* Copyright © 2009 Reinier Zwitserloot and Roel Spilker.
|
||||
*
|
||||
* 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.javac.handlers;
|
||||
|
||||
import java.lang.reflect.Modifier;
|
||||
@@ -16,9 +37,17 @@ import lombok.core.TransformationsUtil;
|
||||
import lombok.core.AST.Kind;
|
||||
import lombok.javac.JavacAST;
|
||||
|
||||
/**
|
||||
* Container for static utility methods relevant to this package.
|
||||
*/
|
||||
class PKG {
|
||||
private PKG() {}
|
||||
private PKG() {
|
||||
//Prevent instantiation
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the likely getter name for the stated field. (e.g. private boolean foo; to isFoo).
|
||||
*/
|
||||
static String toGetterName(JCVariableDecl field) {
|
||||
CharSequence fieldName = field.name;
|
||||
|
||||
@@ -27,16 +56,26 @@ class PKG {
|
||||
return TransformationsUtil.toGetterName(fieldName, isBoolean);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the likely setter name for the stated field. (e.g. private boolean foo; to setFoo).
|
||||
*/
|
||||
static String toSetterName(JCVariableDecl field) {
|
||||
CharSequence fieldName = field.name;
|
||||
|
||||
return TransformationsUtil.toSetterName(fieldName);
|
||||
}
|
||||
|
||||
/** Serves as return value for the methods that check for the existence of fields and methods. */
|
||||
enum MemberExistsResult {
|
||||
NOT_EXISTS, EXISTS_BY_USER, EXISTS_BY_LOMBOK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if there is a field with the provided name.
|
||||
*
|
||||
* @param fieldName the field name to check for.
|
||||
* @param node Any node that represents the Type (JCClassDecl) to check for, or any child node thereof.
|
||||
*/
|
||||
static MemberExistsResult fieldExists(String fieldName, JavacAST.Node node) {
|
||||
while ( node != null && !(node.get() instanceof JCClassDecl) ) {
|
||||
node = node.up();
|
||||
@@ -57,6 +96,13 @@ class PKG {
|
||||
return MemberExistsResult.NOT_EXISTS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if there is a method with the provided name. In case of multiple methods (overloading), only
|
||||
* the first method decides if EXISTS_BY_USER or EXISTS_BY_LOMBOK is returned.
|
||||
*
|
||||
* @param methodName the method name to check for.
|
||||
* @param node Any node that represents the Type (JCClassDecl) to check for, or any child node thereof.
|
||||
*/
|
||||
static MemberExistsResult methodExists(String methodName, JavacAST.Node node) {
|
||||
while ( node != null && !(node.get() instanceof JCClassDecl) ) {
|
||||
node = node.up();
|
||||
@@ -77,6 +123,12 @@ class PKG {
|
||||
return MemberExistsResult.NOT_EXISTS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if there is a (non-default) constructor. In case of multiple constructors (overloading), only
|
||||
* the first constructor decides if EXISTS_BY_USER or EXISTS_BY_LOMBOK is returned.
|
||||
*
|
||||
* @param node Any node that represents the Type (JCClassDecl) to check for, or any child node thereof.
|
||||
*/
|
||||
static MemberExistsResult constructorExists(JavacAST.Node node) {
|
||||
while ( node != null && !(node.get() instanceof JCClassDecl) ) {
|
||||
node = node.up();
|
||||
@@ -98,6 +150,11 @@ class PKG {
|
||||
return MemberExistsResult.NOT_EXISTS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Turns an <code>AccessLevel<code> instance into the flag bit used by javac.
|
||||
*
|
||||
* @see java.lang.Modifier
|
||||
*/
|
||||
static int toJavacModifier(AccessLevel accessLevel) {
|
||||
switch ( accessLevel ) {
|
||||
case MODULE:
|
||||
@@ -113,6 +170,11 @@ class PKG {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the given new field declaration to the provided type AST Node.
|
||||
*
|
||||
* Also takes care of updating the JavacAST.
|
||||
*/
|
||||
static void injectField(JavacAST.Node typeNode, JCVariableDecl field) {
|
||||
JCClassDecl type = (JCClassDecl) typeNode.get();
|
||||
|
||||
@@ -121,6 +183,12 @@ class PKG {
|
||||
typeNode.add(field, Kind.FIELD).recursiveSetHandled();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the given new method declaration to the provided type AST Node.
|
||||
* Can also inject constructors.
|
||||
*
|
||||
* Also takes care of updating the JavacAST.
|
||||
*/
|
||||
static void injectMethod(JavacAST.Node typeNode, JCMethodDecl method) {
|
||||
JCClassDecl type = (JCClassDecl) typeNode.get();
|
||||
|
||||
@@ -154,6 +222,16 @@ class PKG {
|
||||
return out;
|
||||
}
|
||||
|
||||
/**
|
||||
* In javac, dotted access of any kind, from <code>java.lang.String</code> to <code>var.methodName</code>
|
||||
* is represented by a fold-left of <code>Select</code> nodes with the leftmost string represented by
|
||||
* a <code>Ident</code> node. This method generates such an expression.
|
||||
*
|
||||
* For example, maker.Select(maker.Select(maker.Ident(NAME[java]), NAME[lang]), NAME[String]).
|
||||
*
|
||||
* @see com.sun.tools.javac.tree.JCTree.JCIdent
|
||||
* @see com.sun.tools.javac.tree.JCTree.JCFieldAccess
|
||||
*/
|
||||
static JCExpression chainDots(TreeMaker maker, JavacAST.Node node, String... elems) {
|
||||
assert elems != null;
|
||||
assert elems.length > 0;
|
||||
|
||||
@@ -48,9 +48,11 @@ import org.objectweb.asm.Opcodes;
|
||||
* 2-step parsing system, where the bodies of methods aren't filled in until its actually neccessary. Lombok
|
||||
* gets a chance to change the AST immediately after either step.</li>
|
||||
* <li>The <code>parse(MethodDeclaration, CUD)</code>, <code>parse(ConstructorDeclaration, CUD)</code> and
|
||||
* <code>parse(Initializer, TypeDeclaration, CUD)</code> methods could all be theoretically called to
|
||||
* flesh out just one part of a half-finished AST tree. These methods are all instrumented to call Lombok
|
||||
* with the CUD before returning it to whomever wanted it filled out.</li>
|
||||
* <code>parse(Initializer, TypeDeclaration, CUD)</code> methods are all instrumented to not attempt to
|
||||
* complete parsing a method generated by lombok, as the source positions are obviously all wrong
|
||||
* (the method content isn't in the source file!) - lombok has already filled in the complete AST.
|
||||
*
|
||||
* Bit24 on the flags field on all ASTNode objects is used as a marker.</li>
|
||||
*/
|
||||
class EclipseParserTransformer {
|
||||
private static final String COMPILER_PKG =
|
||||
|
||||
Reference in new issue
Block a user