[Git][java-team/lombok-patcher][master] 10 commits: Switch to debhelper-compat = 12.

Markus Koschany gitlab at salsa.debian.org
Fri Aug 2 13:24:13 BST 2019



Markus Koschany pushed to branch master at Debian Java Maintainers / lombok-patcher


Commits:
e5f2e705 by Markus Koschany at 2019-08-02T11:55:24Z
Switch to debhelper-compat = 12.

- - - - -
902ca10e by Markus Koschany at 2019-08-02T11:55:44Z
Declare compliance with Debian Policy 4.4.0.

- - - - -
826362fa by Markus Koschany at 2019-08-02T11:56:31Z
Use canonical VCS-URI

- - - - -
f95a2eae by Markus Koschany at 2019-08-02T11:57:00Z
Remove get-orig-source target

- - - - -
9a314521 by Markus Koschany at 2019-08-02T11:57:30Z
Update jlibs file

- - - - -
c741aa30 by Markus Koschany at 2019-08-02T11:57:42Z
Update copyright years

- - - - -
7f99b7c3 by Markus Koschany at 2019-08-02T11:57:59Z
New upstream version 0.32
- - - - -
92119b71 by Markus Koschany at 2019-08-02T11:58:03Z
Update upstream source from tag 'upstream/0.32'

Update to upstream version '0.32'
with Debian dir 6bb906e148fbdb813df01004121d51b7de9c5ccb
- - - - -
bfa12d37 by Markus Koschany at 2019-08-02T11:58:49Z
Update changelog

- - - - -
88f19832 by Markus Koschany at 2019-08-02T12:20:51Z
Revert "Switch to debhelper-compat = 12."

This reverts commit e5f2e705b8d9fe9395d02db2b88398e93a25827c.

- - - - -


10 changed files:

- debian/changelog
- debian/control
- debian/copyright
- debian/liblombok-patcher-java.jlibs
- debian/rules
- src/patcher/lombok/patcher/Version.java
- src/patcher/lombok/patcher/scripts/ScriptBuilder.java
- src/patcher/lombok/patcher/scripts/WrapReturnValuesScript.java
- test/lombok/patcher/scripts/TestSymbols.java
- test/lombok/patcher/scripts/TestWrapReturnValuesScript.java


Changes:

=====================================
debian/changelog
=====================================
@@ -1,3 +1,12 @@
+lombok-patcher (0.32-1) unstable; urgency=medium
+
+  * New upstream version 0.32.
+  * Declare compliance with Debian Policy 4.4.0.
+  * Use canonical VCS-URI.
+  * Remove get-orig-source target
+
+ -- Markus Koschany <apo at debian.org>  Fri, 02 Aug 2019 13:58:21 +0200
+
 lombok-patcher (0.30-1) unstable; urgency=medium
 
   * New upstream version 0.30.


=====================================
debian/control
=====================================
@@ -15,10 +15,10 @@ Build-Depends:
  libjna-java,
  libjsch-java,
  liblombok-java
-Standards-Version: 4.2.1
+Standards-Version: 4.4.0
 Homepage: https://projectlombok.org
-Vcs-Git: https://anonscm.debian.org/git/pkg-java/lombok-patcher.git
-Vcs-Browser: https://anonscm.debian.org/cgit/pkg-java/lombok-patcher.git
+Vcs-Git: https://salsa.debian.org/java-team/lombok-patcher.git
+Vcs-Browser: https://salsa.debian.org/java-team/lombok-patcher
 
 Package: liblombok-patcher-java
 Architecture: all


=====================================
debian/copyright
=====================================
@@ -7,7 +7,7 @@ Copyright: 2009-2015 The Project Lombok Authors.
 License: Expat
 
 Files: debian/*
-Copyright: 2016-2018, Markus Koschany <apo at debian.org>
+Copyright: 2016-2019, Markus Koschany <apo at debian.org>
 License: Expat
 
 


=====================================
debian/liblombok-patcher-java.jlibs
=====================================
@@ -1,2 +1,2 @@
 dist/lombok.patcher.jar
-dist/lombok.injector-0.30.jar
+dist/lombok.injector-0.32.jar


=====================================
debian/rules
=====================================
@@ -12,6 +12,3 @@ override_dh_auto_clean:
 override_dh_auto_build:
 	mkdir -p build/packInjector
 	ant dist
-
-get-orig-source:
-	uscan --download-current-version --force-download


=====================================
src/patcher/lombok/patcher/Version.java
=====================================
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2009-2018 The Project Lombok Authors.
+ * Copyright (C) 2009-2019 The Project Lombok Authors.
  * 
  * Permission is hereby granted, free of charge, to any person obtaining a copy
  * of this software and associated documentation files (the "Software"), to deal
@@ -26,7 +26,7 @@ package lombok.patcher;
  */
 public class Version {
 	// ** CAREFUL ** - this class must always compile with 0 dependencies (it must not refer to any other sources or libraries).
-	private static final String VERSION = "0.30";
+	private static final String VERSION = "0.32";
 	
 	private Version() {
 		//Prevent instantiation


=====================================
src/patcher/lombok/patcher/scripts/ScriptBuilder.java
=====================================
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2009 The Project Lombok Authors.
+ * Copyright (C) 2009-2019 The Project Lombok Authors.
  * 
  * Permission is hereby granted, free of charge, to any person obtaining a copy
  * of this software and associated documentation files (the "Software"), to deal
@@ -32,6 +32,35 @@ import lombok.patcher.TargetMatcher;
 
 import org.objectweb.asm.Opcodes;
 
+/**
+ * Defines scripts to modify bytecode directly.
+ * 
+ * Some definitions:
+ * 
+ * <h2>transplant</h2>
+ * 
+ * Transplant means that the code you are trying to inject into another class (generally called the {@code hook}) is copied
+ * into the target class. Specifically, you identify a method (the hook) that contains the code that must run as part of the
+ * method targeted for manipulation (the target). Transplantation means that the entire hook method, signature and all, is copied
+ * straight into the target class. You should definitely make the hook static unless you really know what you are doing.<br />
+ * <ul>
+ * <li>Advantage: Your hook is loaded by the same classloader as the target, which helps a lot with classloader issues</li>
+ * <li>Advantage: Whilst you'd have to write it reflectively otherwise your hook can't be compiled, you still get free, unfettered access even to private members of the target</li>
+ * <li>Disadvantage: Because your hook method is moved, you <em>cannot</em> reference <em>anything</em> else from the surroundings of where your hook method lives. Don't make helper methods!
+ * </ul>
+ * 
+ * <h2>insert</h2>
+ * 
+ * Insert is like transplant but even more aggressive: The actual bytecode is dropped straight into the relevant place inside the target
+ * method. insertion only works for extremely simple methods, because no effort is made to ensure that the target location's local space
+ * and/or framesizes are sufficient, and in any case any usage of local slots by your injected code would simply overwrite. Generally,
+ * for one-liners, especially if the one-liner is to replace something with a constant or wrap it with a single method call, you can use it.
+ * 
+ * <h2>cast</h2>
+ * 
+ * This lets you have the method that contains the code you wish to inject simply return {@code java.lang.Object}; this value will be
+ * casted to the required type in the targeted method.
+ */
 public class ScriptBuilder {
 	private ScriptBuilder() throws NoSuchMethodException {
 		throw new NoSuchMethodException("ScriptBuilder cannot be instantiated - just use the static methods.");
@@ -39,12 +68,12 @@ public class ScriptBuilder {
 	
 	private static void checkTypeSyntaxSlash(String spec) {
 		if (spec.indexOf('.') > -1) throw new IllegalArgumentException(
-				"Your type specification includes a dot, but this method wants a slash-separated type specification");
+			"Your type specification includes a dot, but this method wants a slash-separated type specification");
 	}
 	
 	private static void checkTypeSyntaxDot(String spec) {
 		if (spec.indexOf('/') > -1) throw new IllegalArgumentException(
-				"Your type specification includes a slash, but this method wants a dot-separated type specification");
+			"Your type specification includes a slash, but this method wants a dot-separated type specification");
 	}
 	
 	public static class AddFieldBuilder {
@@ -76,6 +105,10 @@ public class ScriptBuilder {
 			return this;
 		}
 		
+		/**
+		 * @param value The value the field should be initialized to. Has to be a constant value of the appropriate type. Optional;
+		 * if skipped, you get the default 0/false/null.
+		 */
 		public AddFieldBuilder value(Object value) {
 			this.value = value;
 			return this;
@@ -151,37 +184,59 @@ public class ScriptBuilder {
 			return new ExitFromMethodEarlyScript(matchers, decisionMethod, valueMethod, transplant, insert, requests);
 		}
 		
+		/**
+		 * The method that you want to modify.
+		 */
 		public ExitEarlyBuilder target(TargetMatcher matcher) {
 			this.matchers.add(matcher);
 			return this;
 		}
 		
+		/**
+		 * The code to be used to decide whether or not a given call should return immediately. If omitted, it's as if you hook
+		 * in the code: {@code return true;}. {@code hook} must be a static method with a {@code boolean} return type.
+		 */
 		public ExitEarlyBuilder decisionMethod(Hook hook) {
 			this.decisionMethod = hook;
 			return this;
 		}
 		
+		/**
+		 * The code to be used to decide the return value. Cannot be specified if {@code target} is a method that returns {@code void},
+		 * otherwise, mandatory. {@code hook} must be a static method with the same return value as {@code target}.
+		 */
 		public ExitEarlyBuilder valueMethod(Hook hook) {
 			this.valueMethod = hook;
 			return this;
 		}
 		
+		/**
+		 * See {@link ScriptBuilder} javadoc for details.
+		 * Applies to both the {@code valueMethod} and the {@code decisionMethod}.
+		 */
 		public ExitEarlyBuilder transplant() {
 			this.transplant = true;
 			this.insert = false;
 			return this;
 		}
 		
+		/**
+		 * See {@link ScriptBuilder} javadoc for details.
+		 * Applies to both the {@code valueMethod} and the {@code decisionMethod}.
+		 */
 		public ExitEarlyBuilder insert() {
 			this.transplant = false;
 			this.insert = true;
 			return this;
 		}
 		
+		/**
+		 * Defines the parameter(s) of your decision and value methods.
+		 */
 		public ExitEarlyBuilder request(StackRequest... requests) {
 			for (StackRequest r : requests) {
 				if (r == StackRequest.RETURN_VALUE) throw new IllegalArgumentException(
-						"You cannot ask for the tentative return value in ExitFromMethodEarlyScript.");
+					"You cannot ask for the tentative return value in ExitFromMethodEarlyScript");
 				this.requests.add(r);
 			}
 			
@@ -204,27 +259,53 @@ public class ScriptBuilder {
 			return new ReplaceMethodCallScript(matchers, methodToReplace, replacementMethod, transplant, insert, extraRequests);
 		}
 		
+		/**
+		 * The method that you want to modify.
+		 */
 		public ReplaceMethodCallBuilder target(TargetMatcher matcher) {
 			this.matchers.add(matcher);
 			return this;
 		}
 		
+		/**
+		 * The method you want to modify is scanned for any calls to {@code methodToReplace}; such calls are then replaced to be
+		 * calls to this method instead. The {@code hook} should be static; its first argument should be the type of receiver
+		 * and then all parameters of the {@code methodToReplace}, and then any further arguments you ask for via {@code requestExtra}.
+		 * <br><br><br>
+		 * Example:<br>
+		 * You target instance method {@code bar} in class {@code Foo}.<br>
+		 * Your methodToReplace is: java.lang.String charAt(int).<br>
+		 * You added {@code StackRequest.THIS} via requestExtra.<br>
+		 * Your replacement method signature should be: {@code public static char replacementCharAt(String receiver, int param1, Foo caller)}.
+		 */
 		public ReplaceMethodCallBuilder replacementMethod(Hook hook) {
 			this.replacementMethod = hook;
 			return this;
 		}
 		
+		/**
+		 * The method you want to modify is scanned for any calls to this specific method; such calls are then replaced to be
+		 * calls to {@code replacementMethod}.
+		 */
 		public ReplaceMethodCallBuilder methodToReplace(Hook hook) {
 			this.methodToReplace = hook;
 			return this;
 		}
 		
+		/**
+		 * See {@link ScriptBuilder} javadoc for details.
+		 * Applies to {@code replacementMethod}.
+		 */
 		public ReplaceMethodCallBuilder transplant() {
 			this.transplant = true;
 			this.insert = false;
 			return this;
 		}
 		
+		/**
+		 * See {@link ScriptBuilder} javadoc for details.
+		 * Applies to {@code replacementMethod}.
+		 */
 		public ReplaceMethodCallBuilder insert() {
 			this.transplant = false;
 			this.insert = true;
@@ -234,7 +315,7 @@ public class ScriptBuilder {
 		public ReplaceMethodCallBuilder requestExtra(StackRequest... requests) {
 			for (StackRequest r : requests) {
 				if (r == StackRequest.RETURN_VALUE) throw new IllegalArgumentException(
-						"You cannot ask for the tentative return value in ReplaceMethodCallScript.");
+					"You cannot ask for the tentative return value in ReplaceMethodCallScript");
 				this.extraRequests.add(r);
 			}
 			
@@ -242,6 +323,10 @@ public class ScriptBuilder {
 		}
 	}
 	
+	/**
+	 * This script scans a target method (The <em>target</em>) for calls to a certain method (The <code>methodToWrap</code>) and
+	 * adds a call to a third method (The <code>wrapMethod</code>), which can inspect and even modify the value.
+	 */
 	public static class WrapMethodCallBuilder {
 		private List<TargetMatcher> matchers = new ArrayList<TargetMatcher>();
 		private Hook wrapMethod;
@@ -257,27 +342,55 @@ public class ScriptBuilder {
 			return new WrapMethodCallScript(matchers, methodToWrap, wrapMethod, transplant, insert, extraRequests);
 		}
 		
+		/**
+		 * The method that you want to modify.
+		 */
 		public WrapMethodCallBuilder target(TargetMatcher matcher) {
 			this.matchers.add(matcher);
 			return this;
 		}
 		
+		/**
+		 * The method you want to modify is scanned for any calls to {@code methodToWrap}; a call to {@code wrapMethod}
+		 * is injected immediately after every call to {@code methodToWrap}.
+		 * The {@code hook} should be static; the returntype of the method you are wrapping should be replicated both as
+		 * the hook's return type and as the type of its first argument. The hook should then have any further arguments
+		 * you ask for via {@code requestExtra}.
+		 * <br><br><br>
+		 * Example:<br>
+		 * You target instance method {@code bar} in class {@code Foo}.<br>
+		 * Your methodToWrap is: java.lang.String charAt(int).<br>
+		 * You added {@code StackRequest.THIS} via requestExtra.<br>
+		 * Your wrap method signature should be: {@code public static char wrapCharAt(char result, Foo caller)}.
+		 */
 		public WrapMethodCallBuilder wrapMethod(Hook hook) {
 			this.wrapMethod = hook;
 			return this;
 		}
 		
+		/**
+		 * The method you want to modify is scanned for any calls to this specific method; calls to {@code wrapMethod}
+		 * are injected immediately following any calls to this method.
+		 */
 		public WrapMethodCallBuilder methodToWrap(Hook hook) {
 			this.methodToWrap = hook;
 			return this;
 		}
 		
+		/**
+		 * See {@link ScriptBuilder} javadoc for details.
+		 * Applies to {@code wrapMethod}.
+		 */
 		public WrapMethodCallBuilder transplant() {
 			this.transplant = true;
 			this.insert = false;
 			return this;
 		}
 		
+		/**
+		 * See {@link ScriptBuilder} javadoc for details.
+		 * Applies to {@code wrapMethod}.
+		 */
 		public WrapMethodCallBuilder insert() {
 			this.transplant = false;
 			this.insert = true;
@@ -287,7 +400,7 @@ public class ScriptBuilder {
 		public WrapMethodCallBuilder requestExtra(StackRequest... requests) {
 			for (StackRequest r : requests) {
 				if (r == StackRequest.RETURN_VALUE) throw new IllegalArgumentException(
-						"You cannot ask for the tentative return value in WrapMethodCallBuilder.");
+					"You cannot ask for the tentative return value in WrapMethodCallBuilder");
 				this.extraRequests.add(r);
 			}
 			
@@ -295,41 +408,69 @@ public class ScriptBuilder {
 		}
 	}
 	
+	/**
+	 * This script lets you inspect (and replace) the returned value for any target method.
+	 */
 	public static class WrapReturnValueBuilder {
 		private List<TargetMatcher> matchers = new ArrayList<TargetMatcher>();
 		private Hook wrapMethod;
 		private Set<StackRequest> requests = new HashSet<StackRequest>();
-		private boolean transplant, insert;
+		private boolean transplant, insert, cast;
 		
 		public WrapReturnValuesScript build() {
 			if (matchers.isEmpty()) throw new IllegalStateException("You have to set a target method matcher");
 			if (wrapMethod == null) throw new IllegalStateException("You have to set a method you'd like to wrap the return values with");
 			
-			return new WrapReturnValuesScript(matchers, wrapMethod, transplant, insert, requests);
+			return new WrapReturnValuesScript(matchers, wrapMethod, transplant, insert, cast, requests);
 		}
 		
+		/**
+		 * The method that you want to modify.
+		 */
 		public WrapReturnValueBuilder target(TargetMatcher matcher) {
 			this.matchers.add(matcher);
 			return this;
 		}
 		
+		/**
+		 * All attempts to return in the {@code target} will be preceded by a call to this {@code hook} immediately prior to the return.
+		 */
 		public WrapReturnValueBuilder wrapMethod(Hook hook) {
 			this.wrapMethod = hook;
 			return this;
 		}
 		
+		/**
+		 * See {@link ScriptBuilder} javadoc for details.
+		 * Applies to {@code wrapMethod}.
+		 */
 		public WrapReturnValueBuilder transplant() {
 			this.transplant = true;
 			this.insert = false;
 			return this;
 		}
 		
+		/**
+		 * See {@link ScriptBuilder} javadoc for details.
+		 * Applies to {@code wrapMethod}.
+		 */
 		public WrapReturnValueBuilder insert() {
+			if (this.cast) throw new IllegalArgumentException("cast and insert are mutually exlusive");
 			this.transplant = false;
 			this.insert = true;
 			return this;
 		}
 		
+		/**
+		 * See {@link ScriptBuilder} javadoc for details.
+		 * Applies to {@code wrapMethod}.
+		 */
+		public WrapReturnValueBuilder cast() {
+			if (this.insert) throw new IllegalArgumentException("insert and cast are mutually exlusive");
+			this.cast = true;
+			return this;
+		}
+		
 		public WrapReturnValueBuilder request(StackRequest... requests) {
 			for (StackRequest r : requests) this.requests.add(r);
 			return this;
@@ -379,21 +520,27 @@ public class ScriptBuilder {
 	}
 	
 	/**
-	 * Allows you patch any method so that you get called first, and you can choose to take over entirely if you want.
+	 * This script lets you modify a target method to return immediately upon being invoked; this can also be used to replace
+	 * entirely what it does.
+	 * Your can control:<br />
+	 * (optional) Have a 'decider' method which decides whether or not a call to the target should return immediately.<br />
+	 * (mandatory) The value to be returned. For void methods this is irrelevant, of course.
 	 */
 	public static ExitEarlyBuilder exitEarly() {
 		return new ExitEarlyBuilder();
 	}
 	
 	/**
-	 * Allows you to replace all calls to a given method in a given method with calls to a method of your choosing.
+	 * This script scans a target method (The <em>target</em>) for calls to a certain method (The <code>methodToReplace</code>) and
+	 * replaces these calls with a different call; usually the replacement is your own creation.
 	 */
 	public static ReplaceMethodCallBuilder replaceMethodCall() {
 		return new ReplaceMethodCallBuilder();
 	}
 	
 	/**
-	 * Allows you to inspect and optionally replace the result of calls to a given method in a given method.
+	 * This script scans a target method (The <em>target</em>) for calls to a certain method (The <code>methodToWrap</code>) and
+	 * adds a call to a third method (The <code>wrapMethod</code>), which can inspect and even modify the value.
 	 */
 	public static WrapMethodCallBuilder wrapMethodCall() {
 		return new WrapMethodCallBuilder();


=====================================
src/patcher/lombok/patcher/scripts/WrapReturnValuesScript.java
=====================================
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2009-2017 The Project Lombok Authors.
+ * Copyright (C) 2009-2019 The Project Lombok Authors.
  * 
  * Permission is hereby granted, free of charge, to any person obtaining a copy
  * of this software and associated documentation files (the "Software"), to deal
@@ -41,7 +41,7 @@ public final class WrapReturnValuesScript extends MethodLevelPatchScript {
 	private final Hook wrapper;
 	private final Set<StackRequest> requests;
 	private final boolean hijackReturnValue;
-	private final boolean transplant, insert;
+	private final boolean transplant, insert, cast;
 	
 	/**
 	 * @param targetMethod The target method to patch.
@@ -50,7 +50,7 @@ public final class WrapReturnValuesScript extends MethodLevelPatchScript {
 	 *   helper methods if you use this!
 	 * @param requests The kinds of parameters you want your hook method to receive.
 	 */
-	WrapReturnValuesScript(List<TargetMatcher> matchers, Hook wrapper, boolean transplant, boolean insert, Set<StackRequest> requests) {
+	WrapReturnValuesScript(List<TargetMatcher> matchers, Hook wrapper, boolean transplant, boolean insert, boolean cast, Set<StackRequest> requests) {
 		super(matchers);
 		if (wrapper == null) throw new NullPointerException("wrapper");
 		this.wrapper = wrapper;
@@ -58,13 +58,15 @@ public final class WrapReturnValuesScript extends MethodLevelPatchScript {
 		this.requests = requests;
 		this.transplant = transplant;
 		this.insert = insert;
+		this.cast = cast && hijackReturnValue;
 		assert !(insert && transplant);
+		assert !(cast && insert);
 	}
 	
 	@Override protected MethodPatcher createPatcher(ClassWriter writer, final String classSpec, TransplantMapper transplantMapper) {
 		final MethodPatcher patcher = new MethodPatcher(writer, transplantMapper, new MethodPatcherFactory() {
 			public MethodVisitor createMethodVisitor(String name, String desc, MethodVisitor parent, MethodLogistics logistics) {
-				return new WrapReturnValues(parent, logistics, classSpec);
+				return new WrapReturnValues(parent, logistics, classSpec, desc);
 			}
 		});
 		
@@ -73,14 +75,25 @@ public final class WrapReturnValuesScript extends MethodLevelPatchScript {
 		return patcher;
 	}
 	
+	private static String extractReturnValueFromDesc(String desc) {
+		int lastIdx = desc == null ? -1 : desc.lastIndexOf(')');
+		if (lastIdx == -1) return null;
+		
+		String rd = desc.substring(lastIdx + 1);
+		if (rd.startsWith("L") && rd.endsWith(";")) return rd.substring(1, rd.length() - 1);
+		return rd;
+	}
+	
 	private class WrapReturnValues extends MethodVisitor {
 		private final MethodLogistics logistics;
 		private final String ownClassSpec;
+		private final String returnValueDesc;
 		
-		public WrapReturnValues(MethodVisitor mv, MethodLogistics logistics, String ownClassSpec) {
+		public WrapReturnValues(MethodVisitor mv, MethodLogistics logistics, String ownClassSpec, String desc) {
 			super(Opcodes.ASM7, mv);
 			this.logistics = logistics;
 			this.ownClassSpec = ownClassSpec;
+			this.returnValueDesc = extractReturnValueFromDesc(desc);
 		}
 		
 		@Override public void visitInsn(int opcode) {
@@ -108,9 +121,14 @@ public final class WrapReturnValuesScript extends MethodLevelPatchScript {
 				logistics.generateLoadOpcodeForParam(param.getParamPos(), mv);
 			}
 			
-			if (insert) insertMethod(wrapper, mv);
-			else super.visitMethodInsn(Opcodes.INVOKESTATIC, transplant ? ownClassSpec : wrapper.getClassSpec(), wrapper.getMethodName(),
+			if (insert) {
+				insertMethod(wrapper, mv);
+			} else {
+				super.visitMethodInsn(Opcodes.INVOKESTATIC, transplant ? ownClassSpec : wrapper.getClassSpec(), wrapper.getMethodName(),
 					wrapper.getMethodDescriptor(), false);
+			}
+			
+			if (cast) super.visitTypeInsn(Opcodes.CHECKCAST, returnValueDesc);
 			super.visitInsn(opcode);
 		}
 	}


=====================================
test/lombok/patcher/scripts/TestSymbols.java
=====================================
@@ -22,7 +22,7 @@
 package lombok.patcher.scripts;
 
 import static lombok.patcher.scripts.ScriptTestUtils.*;
-import static junit.framework.Assert.*;
+import static org.junit.Assert.*;
 
 import java.io.InputStream;
 import java.lang.reflect.Constructor;


=====================================
test/lombok/patcher/scripts/TestWrapReturnValuesScript.java
=====================================
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2009 The Project Lombok Authors.
+ * Copyright (C) 2009-2019 The Project Lombok Authors.
  * 
  * Permission is hereby granted, free of charge, to any person obtaining a copy
  * of this software and associated documentation files (the "Software"), to deal
@@ -57,6 +57,26 @@ public class TestWrapReturnValuesScript {
 		assertEquals("patched return value", 20, (int)(Integer)fooMethod.invoke(ex1Constructor.newInstance(), 5, null));
 	}
 	
+	@Test
+	public void testWrapReturnWithCast() throws Exception {
+		InputStream raw = TestWrapReturnValuesScript.class.getResourceAsStream("/lombok/patcher/scripts/TestWrapReturnValuesScriptEx1.class");
+		byte[] pretransform = readFromStream(raw);
+		byte[] posttransform = ScriptBuilder.wrapReturnValue()
+			.target(new MethodTarget("lombok.patcher.scripts.TestWrapReturnValuesScriptEx1", "bar",
+				"java.lang.String[]"))
+			.wrapMethod(new Hook("lombok.patcher.scripts.TestWrapReturnValuesScript$TestWrapReturnValuesScriptEx2",
+				"hook2", "java.lang.Object", "java.lang.Object"))
+			.cast().request(StackRequest.RETURN_VALUE)
+			.build().patch("lombok/patcher/scripts/TestWrapReturnValuesScriptEx1", pretransform, TransplantMapper.IDENTITY_MAPPER);
+		Class<?> ex1 = loadRaw("lombok.patcher.scripts.TestWrapReturnValuesScriptEx1", posttransform);
+		Method barMethod = ex1.getMethod("bar");
+		Constructor<?> ex1Constructor = ex1.getDeclaredConstructor();
+		barMethod.setAccessible(true);
+		ex1Constructor.setAccessible(true);
+		
+		assertArrayEquals("patched return value", new String[] {"B"}, (String[]) barMethod.invoke(ex1Constructor.newInstance()));
+	}
+	
 	public static class TestWrapReturnValuesScriptEx2 {
 		public static int hook1(int supposedReturnValue, Object thisRef, int param1, String[] param2) {
 			assertEquals("supposedReturnValue", param1 < 10 ? 10 : 80, supposedReturnValue);
@@ -69,6 +89,13 @@ public class TestWrapReturnValuesScript {
 			
 			return supposedReturnValue *2;
 		}
+		
+		public static Object hook2(Object supposedReturnValue) {
+			assertEquals("supposedReturnValue-type", String[].class, supposedReturnValue.getClass());
+			String[] srv = (String[]) supposedReturnValue;
+			assertArrayEquals("supposedReturnValue", new String[] {"A"}, srv);
+			return new String[] {"B"};
+		}
 	}
 }
 
@@ -78,4 +105,8 @@ class TestWrapReturnValuesScriptEx1 {
 		if (x < 10) return 10;
 		return 80;
 	}
+	
+	public String[] bar() {
+		return new String[] {"A"};
+	}
 }



View it on GitLab: https://salsa.debian.org/java-team/lombok-patcher/compare/7719922e17bae3d3273ad376150ded6ffff82ed0...88f19832e41489d07b03c0fbc5f1f323cdc3f971

-- 
View it on GitLab: https://salsa.debian.org/java-team/lombok-patcher/compare/7719922e17bae3d3273ad376150ded6ffff82ed0...88f19832e41489d07b03c0fbc5f1f323cdc3f971
You're receiving this email because of your account on salsa.debian.org.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/pkg-java-commits/attachments/20190802/4dd3eab0/attachment.html>


More information about the pkg-java-commits mailing list