From 08e48a1f1fa04c64e4ffe460e612a60c1e7f0d48 Mon Sep 17 00:00:00 2001 From: Rafael Winterhalter Date: Thu, 7 Jan 2016 14:35:51 +0100 Subject: [PATCH] Completed validation. --- .../description/type/TypeDescription.java | 12 +++++ .../dynamic/scaffold/InstrumentedType.java | 44 +++++++++++++++---- ...escriptionGenericVisitorValidatorTest.java | 2 + .../scaffold/InstrumentedTypeTest.java | 2 + 4 files changed, 51 insertions(+), 9 deletions(-) diff --git a/byte-buddy-dep/src/main/java/net/bytebuddy/description/type/TypeDescription.java b/byte-buddy-dep/src/main/java/net/bytebuddy/description/type/TypeDescription.java index 9896a30eabc..5dc87446a98 100644 --- a/byte-buddy-dep/src/main/java/net/bytebuddy/description/type/TypeDescription.java +++ b/byte-buddy-dep/src/main/java/net/bytebuddy/description/type/TypeDescription.java @@ -1738,12 +1738,24 @@ public String toString() { } } + /** + * A validator for Java types that are defined for a specified type use within a Java class file. + */ enum Validator implements Visitor { + /** + * A validator for checking a type's non-null super class. + */ SUPER_CLASS(false, false, false, false, false), + /** + * A validator for an interface type. + */ INTERFACE(false, false, false, false, false), + /** + * A validator for a type variable, either declared by a + */ TYPE_VARIABLE(false, false, true, false, false), FIELD(true, true, true, false, false), diff --git a/byte-buddy-dep/src/main/java/net/bytebuddy/dynamic/scaffold/InstrumentedType.java b/byte-buddy-dep/src/main/java/net/bytebuddy/dynamic/scaffold/InstrumentedType.java index e100ddc7f49..5c2b998ae18 100644 --- a/byte-buddy-dep/src/main/java/net/bytebuddy/dynamic/scaffold/InstrumentedType.java +++ b/byte-buddy-dep/src/main/java/net/bytebuddy/dynamic/scaffold/InstrumentedType.java @@ -805,10 +805,17 @@ public TypeDescription validated() { } else if (!isValidIdentifier(variableSymbol)) { throw new IllegalStateException("Illegal type variable name of " + typeVariable + " for " + this); } + boolean interfaceBound = false; for (TypeDescription.Generic bound : typeVariable.getUpperBounds()) { if (!bound.accept(Generic.Visitor.Validator.TYPE_VARIABLE)) { - throw new IllegalStateException("Illegal type variable bound " + bound + " of " + typeVariable + "for " + this); + throw new IllegalStateException("Illegal type variable bound " + bound + " of " + typeVariable + " for " + this); + } else if (interfaceBound && (bound.getSort().isTypeVariable() || !bound.asErasure().isInterface())) { + throw new IllegalStateException("Illegal interface bound " + bound + " of " + typeVariable + " for " + this); } + interfaceBound = true; + } + if (!interfaceBound) { + throw new IllegalStateException("Type variable " + typeVariable + " for " + this + " does not define at least one bound"); } } Set typeAnnotationTypes = new HashSet(); @@ -848,10 +855,17 @@ public TypeDescription validated() { } else if (!isValidIdentifier(variableSymbol)) { throw new IllegalStateException("Illegal type variable name of " + typeVariable + " for " + methodDescription); } + boolean interfaceBound = false; for (TypeDescription.Generic bound : typeVariable.getUpperBounds()) { if (!bound.accept(Generic.Visitor.Validator.TYPE_VARIABLE)) { throw new IllegalStateException("Illegal type variable bound " + bound + " of " + typeVariable + " for " + methodDescription); + } else if (interfaceBound && (bound.getSort().isTypeVariable() || !bound.asErasure().isInterface())) { + throw new IllegalStateException("Illegal interface bound " + bound + " of " + typeVariable + " for " + methodDescription); } + interfaceBound = true; + } + if (!interfaceBound) { + throw new IllegalStateException("Type variable " + typeVariable + " for " + methodDescription + " does not define at least one bound"); } } Set methodAnnotationTypes = new HashSet(); @@ -903,11 +917,17 @@ public TypeDescription validated() { return this; } - private static boolean isValidIdentifier(String[] name) { - if (name.length == 0) { + /** + * Checks if an array of identifiers is a valid compound Java identifier. + * + * @param identifier an array of potentially invalid Java identifiers. + * @return {@code true} if all identifiers are valid and the array is not empty. + */ + private static boolean isValidIdentifier(String[] identifier) { + if (identifier.length == 0) { return false; } - for (String part : name) { + for (String part : identifier) { if (!isValidIdentifier(part)) { return false; } @@ -915,14 +935,20 @@ private static boolean isValidIdentifier(String[] name) { return true; } - private static boolean isValidIdentifier(String name) { - if (name.isEmpty() || !Character.isJavaIdentifierStart(name.charAt(0))) { + /** + * Checks if a Java identifier is valid. + * + * @param identifier The identifier to check for validity. + * @return {@code true} if the given identifier is valid. + */ + private static boolean isValidIdentifier(String identifier) { + if (identifier.isEmpty() || !Character.isJavaIdentifierStart(identifier.charAt(0))) { return false; - } else if (name.equals(PackageDescription.PACKAGE_CLASS_NAME)) { + } else if (identifier.equals(PackageDescription.PACKAGE_CLASS_NAME)) { return true; } - for (int index = 1; index < name.length(); index++) { - if (!Character.isJavaIdentifierPart(name.charAt(index))) { + for (int index = 1; index < identifier.length(); index++) { + if (!Character.isJavaIdentifierPart(identifier.charAt(index))) { return false; } } diff --git a/byte-buddy-dep/src/test/java/net/bytebuddy/description/type/TypeDescriptionGenericVisitorValidatorTest.java b/byte-buddy-dep/src/test/java/net/bytebuddy/description/type/TypeDescriptionGenericVisitorValidatorTest.java index ad6b09c2687..0238bede842 100644 --- a/byte-buddy-dep/src/test/java/net/bytebuddy/description/type/TypeDescriptionGenericVisitorValidatorTest.java +++ b/byte-buddy-dep/src/test/java/net/bytebuddy/description/type/TypeDescriptionGenericVisitorValidatorTest.java @@ -12,6 +12,8 @@ public class TypeDescriptionGenericVisitorValidatorTest { + // TODO + @Rule public TestRule mockitoRule = new MockitoRule(this); diff --git a/byte-buddy-dep/src/test/java/net/bytebuddy/dynamic/scaffold/InstrumentedTypeTest.java b/byte-buddy-dep/src/test/java/net/bytebuddy/dynamic/scaffold/InstrumentedTypeTest.java index f13b7897d37..ed82b65ddfe 100644 --- a/byte-buddy-dep/src/test/java/net/bytebuddy/dynamic/scaffold/InstrumentedTypeTest.java +++ b/byte-buddy-dep/src/test/java/net/bytebuddy/dynamic/scaffold/InstrumentedTypeTest.java @@ -472,4 +472,6 @@ public void testInterfaceTypesVisited() throws Exception { verify(typeDescription).asGenericType(); verifyNoMoreInteractions(typeDescription); } + + // TODO: Validation tests }