Author: hlship
Date: Fri Dec 23 18:54:17 2011
New Revision: 1222786
URL: http://svn.apache.org/viewvc?rev=1222786&view=rev
Log:
TAP5-1801: Allow non-public fields in instrumented classes
Added:
tapestry/tapestry5/trunk/plastic/src/test/java/testsubjects/PublicInstanceField.java
- copied, changed from r1221952,
tapestry/tapestry5/trunk/plastic/src/test/java/testsubjects/NonPrivateInstanceField.java
Removed:
tapestry/tapestry5/trunk/plastic/src/test/java/testsubjects/NonPrivateInstanceField.java
Modified:
tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/PlasticClassImpl.java
tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/PlasticFieldImpl.java
tapestry/tapestry5/trunk/plastic/src/test/groovy/org/apache/tapestry5/plastic/ObtainPlasticClass.groovy
Modified:
tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/PlasticClassImpl.java
URL:
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/PlasticClassImpl.java?rev=1222786&r1=1222785&r2=1222786&view=diff
==============================================================================
---
tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/PlasticClassImpl.java
(original)
+++
tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/PlasticClassImpl.java
Fri Dec 23 18:54:17 2011
@@ -222,7 +222,7 @@ public class PlasticClassImpl extends Lo
/**
* Static methods are not visible to the main API methods, but
they must still be transformed,
- * incase they directly access fields. In addition, track their
names to avoid collisions.
+ * in case they directly access fields. In addition, track their
names to avoid collisions.
*/
if (Modifier.isStatic(node.access))
{
@@ -271,16 +271,7 @@ public class PlasticClassImpl extends Lo
if (Modifier.isStatic(node.access))
continue;
- // TODO: Perhaps we should defer this private check until it is
needed,
- // i.e., when we do some work on the field that requires it to be
private?
- // However, given class loading issues, public fields are likely
to cause
- // their own problems when passing the ClassLoader boundary.
-
- if (!Modifier.isPrivate(node.access))
- throw new IllegalArgumentException(
- String.format(
- "Field %s of class %s is not private. Class
transformation requires that all instance fields be private.",
- node.name, className));
+ // When we instrument the field such that it must be private,
we'll get an exception.
fields.add(new PlasticFieldImpl(this, node));
}
Modified:
tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/PlasticFieldImpl.java
URL:
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/PlasticFieldImpl.java?rev=1222786&r1=1222785&r2=1222786&view=diff
==============================================================================
---
tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/PlasticFieldImpl.java
(original)
+++
tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/PlasticFieldImpl.java
Fri Dec 23 18:54:17 2011
@@ -14,8 +14,8 @@
package org.apache.tapestry5.internal.plastic;
-import org.apache.tapestry5.internal.plastic.asm.*;
import org.apache.tapestry5.internal.plastic.asm.Opcodes;
+import org.apache.tapestry5.internal.plastic.asm.Type;
import org.apache.tapestry5.internal.plastic.asm.tree.FieldNode;
import org.apache.tapestry5.internal.plastic.asm.tree.MethodNode;
import org.apache.tapestry5.plastic.*;
@@ -104,9 +104,11 @@ class PlasticFieldImpl extends PlasticMe
plasticClass.check();
if (this.tag != null)
+ {
throw new IllegalStateException(String.format(
"Field %s of class %s can not be claimed by %s as it is
already claimed by %s.", node.name,
plasticClass.className, tag, this.tag));
+ }
this.tag = tag;
@@ -141,8 +143,18 @@ class PlasticFieldImpl extends PlasticMe
private void verifyInitialState(String operation)
{
if (state != FieldState.INITIAL)
+ {
throw new IllegalStateException(String.format("Unable to %s field
%s of class %s, as it already %s.",
operation, node.name, plasticClass.className,
state.description));
+ }
+ }
+
+ private void ensureNotPublic()
+ {
+ if (Modifier.isPublic(node.access))
+ {
+ throw new IllegalArgumentException(String.format("Field %s of
class %s must be instrumented, and may not be public.", node.name,
plasticClass.className));
+ }
}
public PlasticField inject(Object value)
@@ -265,8 +277,6 @@ class PlasticFieldImpl extends PlasticMe
replaceFieldReadAccess(conduitField.getName());
replaceFieldWriteAccess(conduitField.getName());
- // TODO: Do we keep the field or not? It will now always be
null/0/false.
-
state = FieldState.CONDUIT;
return this;
@@ -324,22 +334,26 @@ class PlasticFieldImpl extends PlasticMe
private void introduceAccessorMethod(String returnType, String name,
String[] parameterTypes, String signature,
InstructionBuilderCallback callback)
{
- MethodDescription description = new
MethodDescription(org.apache.tapestry5.internal.plastic.asm.Opcodes.ACC_PUBLIC,
returnType, name, parameterTypes,
+ MethodDescription description = new
MethodDescription(Opcodes.ACC_PUBLIC, returnType, name, parameterTypes,
signature, null);
String desc = plasticClass.nameCache.toDesc(description);
if (plasticClass.inheritanceData.isImplemented(name, desc))
+ {
throw new IllegalArgumentException(String.format(
"Unable to create new accessor method %s on class %s as
the method is already implemented.",
description.toString(), plasticClass.className));
+ }
plasticClass.introduceMethod(description, callback);
}
private void replaceFieldWriteAccess(String conduitFieldName)
{
- String setAccessName =
plasticClass.makeUnique(plasticClass.methodNames, "set_" + node.name);
+ ensureNotPublic();
+
+ String setAccessName =
plasticClass.makeUnique(plasticClass.methodNames, "conduit_set_" + node.name);
setAccess = new MethodNode(Opcodes.ACC_SYNTHETIC | Opcodes.ACC_FINAL,
setAccessName, "(" + node.desc + ")V", null, null);
@@ -372,9 +386,11 @@ class PlasticFieldImpl extends PlasticMe
private void replaceFieldReadAccess(String conduitFieldName)
{
+ ensureNotPublic();
+
boolean writeBehindEnabled = isWriteBehindEnabled();
- String getAccessName =
plasticClass.makeUnique(plasticClass.methodNames, "getfieldvalue_" + node.name);
+ String getAccessName =
plasticClass.makeUnique(plasticClass.methodNames, "conduit_get_" + node.name);
getAccess = new MethodNode(Opcodes.ACC_SYNTHETIC | Opcodes.ACC_FINAL,
getAccessName, "()" + node.desc, null, null);
@@ -441,7 +457,9 @@ class PlasticFieldImpl extends PlasticMe
private void makeReadOnly()
{
- String setAccessName =
plasticClass.makeUnique(plasticClass.methodNames, "setfieldvalue_" + node.name);
+ ensureNotPublic();
+
+ String setAccessName =
plasticClass.makeUnique(plasticClass.methodNames, "reject_field_change_" +
node.name);
setAccess = new MethodNode(Opcodes.ACC_SYNTHETIC | Opcodes.ACC_FINAL,
setAccessName, "(" + node.desc + ")V", null, null);
@@ -462,7 +480,7 @@ class PlasticFieldImpl extends PlasticMe
*/
private MethodNode addShimSetAccessMethod()
{
- String name = plasticClass.makeUnique(plasticClass.methodNames,
"shimset_" + node.name);
+ String name = plasticClass.makeUnique(plasticClass.methodNames,
"shim_set_" + node.name);
// Takes two Object parameters (instance, and value) and returns void.
@@ -482,7 +500,7 @@ class PlasticFieldImpl extends PlasticMe
private MethodNode addShimGetAccessMethod()
{
- String name = plasticClass.makeUnique(plasticClass.methodNames,
"shimget_" + node.name);
+ String name = plasticClass.makeUnique(plasticClass.methodNames,
"shim_get_" + node.name);
MethodNode mn = new MethodNode(Opcodes.ACC_SYNTHETIC |
Opcodes.ACC_FINAL, name, "()" + node.desc, null, null);
Modified:
tapestry/tapestry5/trunk/plastic/src/test/groovy/org/apache/tapestry5/plastic/ObtainPlasticClass.groovy
URL:
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/plastic/src/test/groovy/org/apache/tapestry5/plastic/ObtainPlasticClass.groovy?rev=1222786&r1=1222785&r2=1222786&view=diff
==============================================================================
---
tapestry/tapestry5/trunk/plastic/src/test/groovy/org/apache/tapestry5/plastic/ObtainPlasticClass.groovy
(original)
+++
tapestry/tapestry5/trunk/plastic/src/test/groovy/org/apache/tapestry5/plastic/ObtainPlasticClass.groovy
Fri Dec 23 18:54:17 2011
@@ -107,13 +107,16 @@ class ObtainPlasticClass extends Abstrac
pc.allFields == []
}
- def "instance fields must be private"() {
+ def "instrumented instance fields must be private"() {
when:
- mgr.getPlasticClass("testsubjects.NonPrivateInstanceField")
+
+ PlasticClass pc =
mgr.getPlasticClass("testsubjects.PublicInstanceField")
+
+ pc.getAllFields()[0].inject("fixed string value")
then:
def e = thrown(IllegalArgumentException)
- e.message == "Field shouldBePrivate of class
testsubjects.NonPrivateInstanceField is not private. Class transformation
requires that all instance fields be private."
+ e.message == "Field publicNotAllowed of class
testsubjects.PublicInstanceField must be instrumented, and may not be public."
}
def "original constructors now throw exceptions"() {
Copied:
tapestry/tapestry5/trunk/plastic/src/test/java/testsubjects/PublicInstanceField.java
(from r1221952,
tapestry/tapestry5/trunk/plastic/src/test/java/testsubjects/NonPrivateInstanceField.java)
URL:
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/plastic/src/test/java/testsubjects/PublicInstanceField.java?p2=tapestry/tapestry5/trunk/plastic/src/test/java/testsubjects/PublicInstanceField.java&p1=tapestry/tapestry5/trunk/plastic/src/test/java/testsubjects/NonPrivateInstanceField.java&r1=1221952&r2=1222786&rev=1222786&view=diff
==============================================================================
---
tapestry/tapestry5/trunk/plastic/src/test/java/testsubjects/NonPrivateInstanceField.java
(original)
+++
tapestry/tapestry5/trunk/plastic/src/test/java/testsubjects/PublicInstanceField.java
Fri Dec 23 18:54:17 2011
@@ -14,7 +14,7 @@
package testsubjects;
-public class NonPrivateInstanceField
+public class PublicInstanceField
{
- String shouldBePrivate;
+ public String publicNotAllowed;
}