diff --git a/class-model/pom.xml b/class-model/pom.xml index 709c932bd3..d2f30eb13a 100644 --- a/class-model/pom.xml +++ b/class-model/pom.xml @@ -38,8 +38,8 @@ org.apache.maven.plugins maven-compiler-plugin - 1.6 - 1.6 + 1.8 + 1.8 diff --git a/class-model/src/main/java/org/glassfish/hk2/classmodel/reflect/ClassModel.java b/class-model/src/main/java/org/glassfish/hk2/classmodel/reflect/ClassModel.java index 7537ae58ab..8cc98a7100 100755 --- a/class-model/src/main/java/org/glassfish/hk2/classmodel/reflect/ClassModel.java +++ b/class-model/src/main/java/org/glassfish/hk2/classmodel/reflect/ClassModel.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2018 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2020 Oracle and/or its affiliates. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0, which is available at @@ -13,7 +13,6 @@ * * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 */ - package org.glassfish.hk2.classmodel.reflect; import java.util.Collection; @@ -26,10 +25,10 @@ public interface ClassModel extends ExtensibleType { /** - * Returns an unmodifiable collection of fields models that represent - * all the declared fields of this classes. + * Returns an unmodifiable collection of fields models that represent all + * the declared fields of this classes. * - * @return collection of declared fields + * @return collection of declared fields */ public Collection getFields(); diff --git a/class-model/src/main/java/org/glassfish/hk2/classmodel/reflect/EnumModel.java b/class-model/src/main/java/org/glassfish/hk2/classmodel/reflect/EnumModel.java new file mode 100644 index 0000000000..4662fff54d --- /dev/null +++ b/class-model/src/main/java/org/glassfish/hk2/classmodel/reflect/EnumModel.java @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2020 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0, which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * This Source Code may also be made available under the following Secondary + * Licenses when the conditions for such availability set forth in the + * Eclipse Public License v. 2.0 are satisfied: GNU General Public License, + * version 2 with the GNU Classpath Exception, which is available at + * https://www.gnu.org/software/classpath/license.html. + * + * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 + */ + +package org.glassfish.hk2.classmodel.reflect; + +/** + * + * @author gaurav.gupta@payara.fish + */ +public interface EnumModel { + + Type getType(); + + String getValue(); + +} diff --git a/class-model/src/main/java/org/glassfish/hk2/classmodel/reflect/EnumType.java b/class-model/src/main/java/org/glassfish/hk2/classmodel/reflect/EnumType.java new file mode 100644 index 0000000000..2931e5865e --- /dev/null +++ b/class-model/src/main/java/org/glassfish/hk2/classmodel/reflect/EnumType.java @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2020 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0, which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * This Source Code may also be made available under the following Secondary + * Licenses when the conditions for such availability set forth in the + * Eclipse Public License v. 2.0 are satisfied: GNU General Public License, + * version 2 with the GNU Classpath Exception, which is available at + * https://www.gnu.org/software/classpath/license.html. + * + * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 + */ +package org.glassfish.hk2.classmodel.reflect; + +import java.util.Collection; + +/** + * + * @author gaurav.gupta@payara.fish + */ +public interface EnumType extends ExtensibleType { + + /** + * Returns an unmodifiable collection of fields models that represent all + * the declared fields of this enum. + * + * @return collection of declared fields + */ + public Collection getFields(); + +} diff --git a/class-model/src/main/java/org/glassfish/hk2/classmodel/reflect/ExtensibleType.java b/class-model/src/main/java/org/glassfish/hk2/classmodel/reflect/ExtensibleType.java index 8978af98a7..4d34a370c9 100755 --- a/class-model/src/main/java/org/glassfish/hk2/classmodel/reflect/ExtensibleType.java +++ b/class-model/src/main/java/org/glassfish/hk2/classmodel/reflect/ExtensibleType.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2018 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2020 Oracle and/or its affiliates. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0, which is available at @@ -72,4 +72,11 @@ public interface ExtensibleType extends Type { * @reutrn collection of defined static fields */ Collection getStaticFields(); + + /** + * Returns the unqualified name of the underlying type. + * + * @return the simple name of class + */ + String getSimpleName(); } diff --git a/class-model/src/main/java/org/glassfish/hk2/classmodel/reflect/FieldModel.java b/class-model/src/main/java/org/glassfish/hk2/classmodel/reflect/FieldModel.java index 8406a724a6..d0370a50f1 100755 --- a/class-model/src/main/java/org/glassfish/hk2/classmodel/reflect/FieldModel.java +++ b/class-model/src/main/java/org/glassfish/hk2/classmodel/reflect/FieldModel.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2018 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2020 Oracle and/or its affiliates. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0, which is available at @@ -21,19 +21,39 @@ * * @author Jerome Dochez */ -public interface FieldModel extends Member, AnnotatedElement { +public interface FieldModel extends Member, AnnotatedElement, ParameterizedType { /** * Returns the declared type of the field * * @return the field type */ - public ExtensibleType getType(); + ExtensibleType getType(); + + /** + * Returns the declared type name of the field + * + * @return the field type name + */ + String getTypeName(); /** * Returns the declaring type of this field, which is a class. * * @return the field declaring class. */ - public ExtensibleType getDeclaringType(); + ExtensibleType getDeclaringType(); + + /** + * Returns the declaring type name of this field, which is a class. + * + * @return the field declaring class name. + */ + String getDeclaringTypeName(); + + /** + * + * @return true, if field is marked transient. + */ + boolean isTransient(); } diff --git a/class-model/src/main/java/org/glassfish/hk2/classmodel/reflect/MethodModel.java b/class-model/src/main/java/org/glassfish/hk2/classmodel/reflect/MethodModel.java index c7c0a7fd91..306f817aae 100755 --- a/class-model/src/main/java/org/glassfish/hk2/classmodel/reflect/MethodModel.java +++ b/class-model/src/main/java/org/glassfish/hk2/classmodel/reflect/MethodModel.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2018 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2020 Oracle and/or its affiliates. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0, which is available at @@ -16,6 +16,8 @@ package org.glassfish.hk2.classmodel.reflect; +import java.util.List; + /** * Model to represent a method declaration */ @@ -37,11 +39,26 @@ public interface MethodModel extends Member, AnnotatedElement { * Returns the method return type * @return the method's return type */ - String getReturnType(); + ParameterizedType getReturnType(); /** * Returns the parameter types as string * @return the parameter types */ String[] getArgumentTypes(); + + /** + * Returns the list of parameter + * + * @return the list of parameter + */ + List getParameters(); + + /** + * Return the parameter by index + * + * @param index + * @return the parameter by index + */ + Parameter getParameter(int index); } diff --git a/class-model/src/main/java/org/glassfish/hk2/classmodel/reflect/Parameter.java b/class-model/src/main/java/org/glassfish/hk2/classmodel/reflect/Parameter.java index c750c91d6c..f0918caf2d 100755 --- a/class-model/src/main/java/org/glassfish/hk2/classmodel/reflect/Parameter.java +++ b/class-model/src/main/java/org/glassfish/hk2/classmodel/reflect/Parameter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2018 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2020 Oracle and/or its affiliates. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0, which is available at @@ -21,7 +21,7 @@ * * @author Jerome Dochez */ -public interface Parameter extends AnnotatedElement { +public interface Parameter extends AnnotatedElement, ParameterizedType { /** * Parameters of a method are ordered based on the method @@ -35,5 +35,12 @@ public interface Parameter extends AnnotatedElement { * Returns the parameter type * @return parameter type */ - public ExtensibleType getType(); + public Type getType(); + + /** + * Returns the parameter index + * + * @return parameter index + */ + public int getIndex(); } diff --git a/class-model/src/main/java/org/glassfish/hk2/classmodel/reflect/ParameterizedType.java b/class-model/src/main/java/org/glassfish/hk2/classmodel/reflect/ParameterizedType.java new file mode 100644 index 0000000000..b5e4541fd2 --- /dev/null +++ b/class-model/src/main/java/org/glassfish/hk2/classmodel/reflect/ParameterizedType.java @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2020 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0, which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * This Source Code may also be made available under the following Secondary + * Licenses when the conditions for such availability set forth in the + * Eclipse Public License v. 2.0 are satisfied: GNU General Public License, + * version 2 with the GNU Classpath Exception, which is available at + * https://www.gnu.org/software/classpath/license.html. + * + * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 + */ +package org.glassfish.hk2.classmodel.reflect; + +import java.util.List; + +/** + * Denote a Generic type that is parameterized over types + * + * @author gaurav.gupta@payara.fish + */ +public interface ParameterizedType { + + Type getType(); + + String getTypeName(); + + List getGenericTypes(); +} diff --git a/class-model/src/main/java/org/glassfish/hk2/classmodel/reflect/impl/ClassModelImpl.java b/class-model/src/main/java/org/glassfish/hk2/classmodel/reflect/impl/ClassModelImpl.java index dd4ac0a760..cc9f992280 100755 --- a/class-model/src/main/java/org/glassfish/hk2/classmodel/reflect/impl/ClassModelImpl.java +++ b/class-model/src/main/java/org/glassfish/hk2/classmodel/reflect/impl/ClassModelImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2018 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2020 Oracle and/or its affiliates. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0, which is available at @@ -18,7 +18,6 @@ import org.glassfish.hk2.classmodel.reflect.*; -import java.net.URI; import java.util.*; /** @@ -26,12 +25,13 @@ */ public class ClassModelImpl extends ExtensibleTypeImpl implements ClassModel { - final List fields = new ArrayList (); + final List fields = new ArrayList<>(); public ClassModelImpl(String name, TypeProxy sink, TypeProxy parent) { super(name, sink, parent); } + @Override synchronized void addField(FieldModel field) { fields.add(field); } @@ -50,4 +50,5 @@ protected void print(StringBuffer sb) { } sb.append("]"); } + } diff --git a/class-model/src/main/java/org/glassfish/hk2/classmodel/reflect/impl/EnumModelImpl.java b/class-model/src/main/java/org/glassfish/hk2/classmodel/reflect/impl/EnumModelImpl.java new file mode 100644 index 0000000000..fb0cdcbfde --- /dev/null +++ b/class-model/src/main/java/org/glassfish/hk2/classmodel/reflect/impl/EnumModelImpl.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2020 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0, which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * This Source Code may also be made available under the following Secondary + * Licenses when the conditions for such availability set forth in the + * Eclipse Public License v. 2.0 are satisfied: GNU General Public License, + * version 2 with the GNU Classpath Exception, which is available at + * https://www.gnu.org/software/classpath/license.html. + * + * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 + */ + +package org.glassfish.hk2.classmodel.reflect.impl; + +import org.glassfish.hk2.classmodel.reflect.*; + +/** + * + * @author gaurav.gupta@payara.fish + */ +public class EnumModelImpl implements EnumModel { + + private final Type type; + + private final String value; + + public EnumModelImpl(Type type, String value) { + this.type = type; + this.value = value; + } + + @Override + public Type getType() { + return type; + } + + @Override + public String getValue() { + return value; + } + + @Override + public String toString() { + return value; + } +} diff --git a/class-model/src/main/java/org/glassfish/hk2/classmodel/reflect/impl/EnumTypeImpl.java b/class-model/src/main/java/org/glassfish/hk2/classmodel/reflect/impl/EnumTypeImpl.java new file mode 100644 index 0000000000..3fadca4752 --- /dev/null +++ b/class-model/src/main/java/org/glassfish/hk2/classmodel/reflect/impl/EnumTypeImpl.java @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2020 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0, which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * This Source Code may also be made available under the following Secondary + * Licenses when the conditions for such availability set forth in the + * Eclipse Public License v. 2.0 are satisfied: GNU General Public License, + * version 2 with the GNU Classpath Exception, which is available at + * https://www.gnu.org/software/classpath/license.html. + * + * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 + */ +package org.glassfish.hk2.classmodel.reflect.impl; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import org.glassfish.hk2.classmodel.reflect.*; + +/** + * + * @author gaurav.gupta@payara.fish + */ +public class EnumTypeImpl extends ExtensibleTypeImpl implements EnumType { + + final List fields = new ArrayList<>(); + + public EnumTypeImpl(String name, TypeProxy sink, TypeProxy parent) { + super(name, sink, parent); + } + + @Override + synchronized void addField(FieldModel field) { + fields.add(field); + } + + @Override + public Collection getFields() { + return Collections.unmodifiableCollection(fields); + } + +} diff --git a/class-model/src/main/java/org/glassfish/hk2/classmodel/reflect/impl/ExtensibleTypeImpl.java b/class-model/src/main/java/org/glassfish/hk2/classmodel/reflect/impl/ExtensibleTypeImpl.java index 5cefdd763e..e3b4666bda 100755 --- a/class-model/src/main/java/org/glassfish/hk2/classmodel/reflect/impl/ExtensibleTypeImpl.java +++ b/class-model/src/main/java/org/glassfish/hk2/classmodel/reflect/impl/ExtensibleTypeImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2018 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2020 Oracle and/or its affiliates. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0, which is available at @@ -38,14 +38,23 @@ public ExtensibleTypeImpl(String name, TypeProxy sink, TypeProxy parent) { this.parent = parent; } + @Override public T getParent() { - if (parent!=null) { + if (parent != null) { return (T) parent.get(); } else { return null; } } - + + @Override + public String getSimpleName() { + String simpleName = getName(); + simpleName = simpleName.substring(simpleName.lastIndexOf('.') + 1); + simpleName = simpleName.substring(simpleName.lastIndexOf('$') + 1); + return simpleName; + } + public synchronized TypeProxy setParent(final TypeProxy parent) { if (null == this.parent) { this.parent = parent; diff --git a/class-model/src/main/java/org/glassfish/hk2/classmodel/reflect/impl/FieldModelImpl.java b/class-model/src/main/java/org/glassfish/hk2/classmodel/reflect/impl/FieldModelImpl.java index 69cd6489f7..3608b265de 100755 --- a/class-model/src/main/java/org/glassfish/hk2/classmodel/reflect/impl/FieldModelImpl.java +++ b/class-model/src/main/java/org/glassfish/hk2/classmodel/reflect/impl/FieldModelImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2018 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2020 Oracle and/or its affiliates. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0, which is available at @@ -16,24 +16,36 @@ package org.glassfish.hk2.classmodel.reflect.impl; -import org.glassfish.hk2.classmodel.reflect.ClassModel; +import java.util.ArrayList; +import java.util.List; import org.glassfish.hk2.classmodel.reflect.ExtensibleType; import org.glassfish.hk2.classmodel.reflect.FieldModel; +import org.glassfish.hk2.classmodel.reflect.ParameterizedType; +import org.objectweb.asm.Opcodes; /** * Implementation of a field model */ public class FieldModelImpl extends AnnotatedElementImpl implements FieldModel { - final TypeProxy type; private final ExtensibleType declaringType; + final TypeProxy type; + + private int access; + + private final List genericTypes = new ArrayList<>(); + public FieldModelImpl(String name, TypeProxy type, ExtensibleType declaringType) { super(name); this.type = type; this.declaringType = declaringType; } + public void setAccess(int access) { + this.access = access; + } + @Override public Type getMemberType() { return Type.FIELD; @@ -44,14 +56,34 @@ public ExtensibleType getDeclaringType() { return declaringType; } + @Override + public String getDeclaringTypeName() { + return type.getName(); + } + @Override public ExtensibleType getType() { return (ExtensibleType) type.get(); } + @Override + public String getTypeName() { + return type.getName(); + } + @Override protected void print(StringBuffer sb) { super.print(sb); sb.append(", type =").append(type.getName()); } + + @Override + public List getGenericTypes() { + return genericTypes; + } + + @Override + public boolean isTransient() { + return (Opcodes.ACC_TRANSIENT & access) == Opcodes.ACC_TRANSIENT; + } } diff --git a/class-model/src/main/java/org/glassfish/hk2/classmodel/reflect/impl/MethodModelImpl.java b/class-model/src/main/java/org/glassfish/hk2/classmodel/reflect/impl/MethodModelImpl.java index 094e15056f..b622517aad 100755 --- a/class-model/src/main/java/org/glassfish/hk2/classmodel/reflect/impl/MethodModelImpl.java +++ b/class-model/src/main/java/org/glassfish/hk2/classmodel/reflect/impl/MethodModelImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2018 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2020 Oracle and/or its affiliates. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0, which is available at @@ -18,7 +18,6 @@ import org.glassfish.hk2.classmodel.reflect.*; -import java.util.ArrayList; import java.util.List; /** @@ -26,9 +25,10 @@ */ public class MethodModelImpl extends AnnotatedElementImpl implements MethodModel { - final List parameters = new ArrayList(); + private List parameters; + private ParameterizedType returnType; final ExtensibleType owner; - final String signature; + private final String signature; public MethodModelImpl(String name, ExtensibleType owner, String signature) { super(name); @@ -52,17 +52,43 @@ public String getSignature() { } @Override - public String getReturnType() { - return org.objectweb.asm.Type.getReturnType(signature).getClassName(); + public ParameterizedType getReturnType() { + return returnType; + } + + public void setReturnType(ParameterizedType returnType) { + this.returnType = returnType; } @Override public String[] getArgumentTypes() { - org.objectweb.asm.Type[] types = org.objectweb.asm.Type.getArgumentTypes(signature); - String[] stringTypes = new String[types.length]; - for (int i=0;i getParameters() { + return parameters; + } + + @Override + public Parameter getParameter(int index) { + if (parameters != null) { + return parameters.get(index); + } + return null; + } + + public void setParameters(List parameters) { + this.parameters = parameters; + } + } diff --git a/class-model/src/main/java/org/glassfish/hk2/classmodel/reflect/impl/MethodSignatureVisitorImpl.java b/class-model/src/main/java/org/glassfish/hk2/classmodel/reflect/impl/MethodSignatureVisitorImpl.java new file mode 100644 index 0000000000..22b1fac6a6 --- /dev/null +++ b/class-model/src/main/java/org/glassfish/hk2/classmodel/reflect/impl/MethodSignatureVisitorImpl.java @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2020 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0, which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * This Source Code may also be made available under the following Secondary + * Licenses when the conditions for such availability set forth in the + * Eclipse Public License v. 2.0 are satisfied: GNU General Public License, + * version 2 with the GNU Classpath Exception, which is available at + * https://www.gnu.org/software/classpath/license.html. + * + * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 + */ +package org.glassfish.hk2.classmodel.reflect.impl; + +import org.glassfish.hk2.classmodel.reflect.InterfaceModel; +import org.objectweb.asm.Opcodes; +import org.objectweb.asm.signature.SignatureVisitor; + +import java.util.*; +import org.glassfish.hk2.classmodel.reflect.MethodModel; +import org.glassfish.hk2.classmodel.reflect.Parameter; +import org.glassfish.hk2.classmodel.reflect.ParameterizedType; + +/** + * Signature visitor to visit method parameters, return type and respective + * generic types + * + * @author gaurav.gupta@payara.fish + */ +public class MethodSignatureVisitorImpl extends SignatureVisitor { + + private final TypeBuilder typeBuilder; + private final MethodModel methodModel; + + private final List parameters = new ArrayList<>(); + private final ParameterizedType returnType = new ParameterizedTypeImpl(); + private final ArrayDeque parentType = new ArrayDeque<>(); + + public MethodSignatureVisitorImpl(TypeBuilder typeBuilder, MethodModel methodModel) { + super(Opcodes.ASM7); + + this.typeBuilder = typeBuilder; + this.methodModel = methodModel; + } + + public List getParameters() { + return parameters; + } + + public ParameterizedType getReturnType() { + return returnType; + } + + @Override + public SignatureVisitor visitParameterType() { + ParameterImpl parameter = new ParameterImpl(parameters.size(), null, methodModel); + parameters.add(parameter); + parentType.add(parameter); + return this; + } + + @Override + public SignatureVisitor visitReturnType() { + parentType.add(returnType); + return this; + } + + @Override + public void visitClassType(String name) { + String className = org.objectweb.asm.Type.getObjectType(name).getClassName(); + TypeProxy typeProxy = typeBuilder.getHolder(className); + if (typeProxy != null) { + if (!parentType.isEmpty()) { + ParameterizedType current = parentType.peekLast(); + if (current instanceof ParameterImpl + && ((ParameterImpl) current).getTypeProxy() == null) { + ((ParameterImpl) current).setTypeProxy(typeProxy); + } else if (current instanceof ParameterizedTypeImpl + && ((ParameterizedTypeImpl) current).getTypeProxy() == null) { + ((ParameterizedTypeImpl) current).setTypeProxy(typeProxy); + } else { + ParameterizedTypeImpl genericType = new ParameterizedTypeImpl(typeProxy); + current.getGenericTypes().add(genericType); + parentType.add(genericType); + } + } + } + } + + @Override + public SignatureVisitor visitTypeArgument(char c) { + return this; + } + + @Override + public void visitEnd() { + parentType.pollLast(); + } +} diff --git a/class-model/src/main/java/org/glassfish/hk2/classmodel/reflect/impl/ModelClassVisitor.java b/class-model/src/main/java/org/glassfish/hk2/classmodel/reflect/impl/ModelClassVisitor.java index abbc054c46..a26b953629 100755 --- a/class-model/src/main/java/org/glassfish/hk2/classmodel/reflect/impl/ModelClassVisitor.java +++ b/class-model/src/main/java/org/glassfish/hk2/classmodel/reflect/impl/ModelClassVisitor.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2018 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2020 Oracle and/or its affiliates. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0, which is available at @@ -23,6 +23,10 @@ import java.net.URI; import java.net.URISyntaxException; +import java.util.ArrayDeque; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; @@ -48,8 +52,8 @@ public class ModelClassVisitor extends ClassVisitor { private final ModelMethodVisitor methodVisitor; private final ModelAnnotationVisitor annotationVisitor; private final ModelDefaultAnnotationVisitor defaultAnnotationVisitor; - private static int discarded=0; - private boolean isApplicationClass; + private static final int discarded = 0; + private final boolean isApplicationClass; public ModelClassVisitor(ParsingContext ctx, URI definingURI, String entryName, @@ -188,7 +192,7 @@ public AnnotationVisitor visitAnnotation(String desc, boolean visible) { logger.log(Level.FINER, "Inspecting fields of {0}", type.getName()); deepVisit =true; } - annotationVisitor.getContext().annotation=am; + annotationVisitor.setAnnotation(am); return annotationVisitor; } @@ -211,18 +215,24 @@ public FieldVisitor visitField(int access, final String name, final String desc, ExtensibleTypeImpl cm; if (!(type instanceof ExtensibleTypeImpl)) { - logger.severe("Field visitor invoked for field " + name + - "in type " + type.getName() + " which is not a ClassModel type instance but a " - + type.getClass().getName()); + logger.log( + Level.SEVERE, + "Field visitor invoked for field {0}in type {1} which is not a ClassModel type instance but a {2}", + new Object[]{name, type.getName(), type.getClass().getName()} + ); return null; } cm = (ExtensibleTypeImpl) type; org.objectweb.asm.Type asmType = org.objectweb.asm.Type.getType(desc); - TypeProxy fieldType = typeBuilder.getHolder(asmType.getClassName()); - if (fieldType==null) return null; + TypeProxy fieldType = typeBuilder.getHolder(asmType.getClassName()); + if (fieldType == null) { + return null; + } + final FieldModelImpl field = typeBuilder.getFieldModel(name, fieldType, cm); + field.setAccess(access); fieldVisitor.getContext().field = field; fieldVisitor.getContext().typeDesc = desc; fieldVisitor.getContext().access = access; @@ -240,14 +250,40 @@ public MethodVisitor visitMethod(int access, String name, String desc, String si ExtensibleType cm; if (!(type instanceof ExtensibleType)) { - logger.severe("Method visitor invoked for method " + name + - "in type " + type.getName() + " which is not an ExtensibleType type instance but a " - + type.getClass().getName()); + logger.log( + Level.SEVERE, + "Method visitor invoked for method {0} in type {1} which is not an ExtensibleType type instance but a {2}", + new Object[]{name, type.getName(), type.getClass().getName()} + ); return null; } cm = (ExtensibleType) type; + MethodModelImpl methodModel = new MethodModelImpl( + name, cm, (signature == null ? desc : signature) + ); + + SignatureReader reader = new SignatureReader(signature == null ? desc : signature); + MethodSignatureVisitorImpl visitor = new MethodSignatureVisitorImpl(typeBuilder, methodModel); + reader.accept(visitor); + + methodModel.setParameters(visitor.getParameters()); + methodModel.setReturnType(visitor.getReturnType()); + + // fallback for void, primitive data types, java.lang.Object and generic wildcards types + ParameterizedTypeImpl returnType = (ParameterizedTypeImpl) methodModel.getReturnType(); + if (returnType.getTypeProxy() == null) { + returnType.setTypeName(org.objectweb.asm.Type.getReturnType(desc).getClassName()); + } + + org.objectweb.asm.Type[] types = org.objectweb.asm.Type.getArgumentTypes(desc); + for (int i = 0; i < methodModel.getParameters().size(); i++) { + ParameterImpl parameter = (ParameterImpl) methodModel.getParameter(i); + if (parameter.getTypeProxy() == null) { + parameter.setTypeName(types[i].getClassName()); + } + } - methodVisitor.getContext().method = new MethodModelImpl(name, cm, (signature==null?desc:signature)); + methodVisitor.getContext().method = methodModel; return methodVisitor; } @@ -295,6 +331,7 @@ private MethodVisitingContext(boolean modelUnAnnotatedMembers) { private static class AnnotationVisitingContext { AnnotationModelImpl annotation; + ArrayDeque parent = new ArrayDeque(); } private class ModelMethodVisitor extends MethodVisitor { @@ -319,15 +356,35 @@ public AnnotationVisitor visitAnnotation(String desc, boolean visible) { } AnnotationTypeImpl annotationType = (AnnotationTypeImpl) typeBuilder.getType(Opcodes.ACC_ANNOTATION, unwrap(desc), null); - AnnotationModelImpl am = new AnnotationModelImpl(context.method, annotationType); + AnnotationModelImpl annotationModel = new AnnotationModelImpl(context.method, annotationType); - // reverse index. + // reverse index annotationType.getAnnotatedElements().add(context.method); // forward index - context.method.addAnnotation(am); - annotationVisitor.getContext().annotation= am; + context.method.addAnnotation(annotationModel); + annotationVisitor.setAnnotation(annotationModel); + return annotationVisitor; + } + + @Override + public AnnotationVisitor visitParameterAnnotation( + final int parameterIndex, + final String desc, + final boolean visible + ) { + AnnotationTypeImpl annotationType = (AnnotationTypeImpl) typeBuilder.getType(Opcodes.ACC_ANNOTATION, unwrap(desc), null); + ParameterImpl parameter = (ParameterImpl) context.method.getParameter(parameterIndex); + + AnnotationModelImpl annotationModel = new AnnotationModelImpl(parameter, annotationType); + + // reverse index. + annotationType.getAnnotatedElements().add(parameter); + + // forward index + parameter.addAnnotation(annotationModel); + annotationVisitor.setAnnotation(annotationModel); return annotationVisitor; } @@ -348,27 +405,27 @@ public AnnotationVisitor visitAnnotationDefault() { private class ModelDefaultAnnotationVisitor extends AnnotationVisitor { - private final MethodVisitingContext context; - - public ModelDefaultAnnotationVisitor(MethodVisitingContext visitingContext) { - super(Opcodes.ASM7); - this.context = visitingContext; - } - - public void visit(java.lang.String desc, java.lang.Object value) { - AnnotationTypeImpl am = (AnnotationTypeImpl) context.method.owner; - am.addDefaultValue(context.method.getName(), value); - } + private final MethodVisitingContext context; + + public ModelDefaultAnnotationVisitor(MethodVisitingContext visitingContext) { + super(Opcodes.ASM7); + this.context = visitingContext; + } + + @Override + public void visit(java.lang.String desc, java.lang.Object value) { + AnnotationTypeImpl am = (AnnotationTypeImpl) context.method.owner; + am.addDefaultValue(context.method.getName(), value); + } } - private class ModelFieldVisitor extends FieldVisitor { private final FieldVisitingContext context; private ModelFieldVisitor(MemberVisitingContext context) { super(Opcodes.ASM7); - + this.context = new FieldVisitingContext(context.modelUnAnnotatedMembers); } @@ -380,7 +437,7 @@ FieldVisitingContext getContext() { public AnnotationVisitor visitAnnotation(String s, boolean b) { FieldModelImpl field = context.field; - AnnotationTypeImpl annotationType = (AnnotationTypeImpl) typeBuilder.getType(Opcodes.ACC_ANNOTATION, unwrap(s), null ); + AnnotationTypeImpl annotationType = (AnnotationTypeImpl) typeBuilder.getType(Opcodes.ACC_ANNOTATION, unwrap(s), null); AnnotationModelImpl annotationModel = new AnnotationModelImpl(field, annotationType); // reverse index. @@ -388,7 +445,7 @@ public AnnotationVisitor visitAnnotation(String s, boolean b) { // forward index field.addAnnotation(annotationModel); - annotationVisitor.getContext().annotation = annotationModel; + annotationVisitor.setAnnotation(annotationModel); return annotationVisitor; } @@ -402,7 +459,7 @@ public void visitEnd() { context.field.type.addFieldRef(context.field); // forward index - if ((Opcodes.ACC_STATIC & context.access)==Opcodes.ACC_STATIC) { + if ((Opcodes.ACC_STATIC & context.access) == Opcodes.ACC_STATIC) { context.classModel.addStaticField(context.field); } else { context.classModel.addField(context.field); @@ -414,36 +471,103 @@ public void visitEnd() { } private class ModelAnnotationVisitor extends AnnotationVisitor { + private final AnnotationVisitingContext context; private ModelAnnotationVisitor() { super(Opcodes.ASM7); - + this.context = new AnnotationVisitingContext(); } AnnotationVisitingContext getContext() { return context; } - + + void setAnnotation(AnnotationModelImpl annotation) { + this.context.annotation = annotation; + context.parent.add(annotation); + } + @Override public void visit(String name, Object value) { - if (context.annotation==null) return; - context.annotation.addValue(name, value); + addValue(name, value); } - + @Override public AnnotationVisitor visitArray(String name) { - if (context.annotation == null) return null; - context.annotation.addValue(name, null); - return null; - + ArrayVisitor arrayVisitor = new ArrayVisitor(annotationVisitor); + addValue(name, arrayVisitor.getValues()); + context.parent.add(arrayVisitor.getValues()); + return arrayVisitor; + } + + private void addValue(String name, Object value) { + if (!context.parent.isEmpty()) { + Object parent = context.parent.peekLast(); + if (parent instanceof AnnotationModelImpl) { + ((AnnotationModelImpl) parent).addValue(name, value); + } else if (parent instanceof List) { + ((List) parent).add(value); + } else if (parent instanceof Map) { + ((Map) parent).put(name, value); + } else { + throw new IllegalStateException(); + } + } + } + + @Override + public void visitEnum(String name, String desc, String value) { + final Type type = (Type) typeBuilder.getType(Opcodes.ACC_ENUM, unwrap(desc), null); + final EnumModel enumModel = new EnumModelImpl(type, value); + + addValue(name, enumModel); + } + + @Override + public AnnotationVisitor visitAnnotation(String name, String desc) { + desc = unwrap(desc); + + final AnnotationTypeImpl at = (AnnotationTypeImpl) typeBuilder.getType(Opcodes.ACC_ANNOTATION, desc, null); + final AnnotationModelImpl am = new AnnotationModelImpl(null, at); + + addValue(name, am); + context.parent.add(am); + return annotationVisitor; } @Override public void visitEnd() { -// context.annotation=null; + if (!context.parent.isEmpty()) { + context.parent.pollLast(); + } } } - + + private class ArrayVisitor extends AnnotationVisitor { + + protected List values = new ArrayList(); + + public ArrayVisitor(AnnotationVisitor av) { + super(Opcodes.ASM7, av); + } + + @Override + public void visit(String name, Object value) { + values.add(unwrap(value)); + } + + private Object unwrap(Object value) { + if (org.objectweb.asm.Type.class.isInstance(value)) { + return org.objectweb.asm.Type.class.cast(value).getClassName(); + } + return value; + } + + public List getValues() { + return values; + } + } + } diff --git a/class-model/src/main/java/org/glassfish/hk2/classmodel/reflect/impl/ParameterImpl.java b/class-model/src/main/java/org/glassfish/hk2/classmodel/reflect/impl/ParameterImpl.java new file mode 100644 index 0000000000..deb33a0a3c --- /dev/null +++ b/class-model/src/main/java/org/glassfish/hk2/classmodel/reflect/impl/ParameterImpl.java @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2020 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0, which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * This Source Code may also be made available under the following Secondary + * Licenses when the conditions for such availability set forth in the + * Eclipse Public License v. 2.0 are satisfied: GNU General Public License, + * version 2 with the GNU Classpath Exception, which is available at + * https://www.gnu.org/software/classpath/license.html. + * + * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 + */ +package org.glassfish.hk2.classmodel.reflect.impl; + +import java.util.ArrayList; +import java.util.List; +import org.glassfish.hk2.classmodel.reflect.MethodModel; +import org.glassfish.hk2.classmodel.reflect.Parameter; +import org.glassfish.hk2.classmodel.reflect.Type; +import org.glassfish.hk2.classmodel.reflect.ParameterizedType; + +/** + * + * @author gaurav.gupta@payara.fish + */ +public class ParameterImpl extends AnnotatedElementImpl implements Parameter { + + private final MethodModel methodModel; + + private TypeProxy type; + + private String typeName; + + private final int index; + + private final List genericTypes = new ArrayList<>(); + + public ParameterImpl(int index, String name, TypeProxy type, MethodModel methodModel) { + super(name); + this.index = index; + this.type = type; + this.methodModel = methodModel; + } + + public ParameterImpl(int index, String name, MethodModel methodModel) { + super(name); + this.index = index; + this.methodModel = methodModel; + } + + @Override + public MethodModel getMethod() { + return methodModel; + } + + @Override + public Type getType() { + return type.get(); + } + + @Override + public String getTypeName() { + if (type == null) { + return typeName; + } + return type.getName(); + } + + public void setTypeName(String typeName) { + this.typeName = typeName; + } + + public TypeProxy getTypeProxy() { + return type; + } + + public void setTypeProxy(TypeProxy type) { + this.type = type; + } + + @Override + public List getGenericTypes() { + return genericTypes; + } + + @Override + protected void print(StringBuffer sb) { + super.print(sb); + sb.append(", type =").append(this.getTypeName()); + } + + @Override + public int getIndex() { + return index; + } +} diff --git a/class-model/src/main/java/org/glassfish/hk2/classmodel/reflect/impl/ParameterizedTypeImpl.java b/class-model/src/main/java/org/glassfish/hk2/classmodel/reflect/impl/ParameterizedTypeImpl.java new file mode 100644 index 0000000000..40efb8b305 --- /dev/null +++ b/class-model/src/main/java/org/glassfish/hk2/classmodel/reflect/impl/ParameterizedTypeImpl.java @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2020 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0, which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * This Source Code may also be made available under the following Secondary + * Licenses when the conditions for such availability set forth in the + * Eclipse Public License v. 2.0 are satisfied: GNU General Public License, + * version 2 with the GNU Classpath Exception, which is available at + * https://www.gnu.org/software/classpath/license.html. + * + * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 + */ +package org.glassfish.hk2.classmodel.reflect.impl; + +import java.util.ArrayList; +import java.util.List; +import org.glassfish.hk2.classmodel.reflect.Type; +import org.glassfish.hk2.classmodel.reflect.ParameterizedType; + +/** + * + * @author gaurav.gupta@payara.fish + */ +public class ParameterizedTypeImpl implements ParameterizedType { + + private TypeProxy type; + + private String typeName; + + private final List genericTypes = new ArrayList<>(); + + public ParameterizedTypeImpl() { + } + + public ParameterizedTypeImpl(TypeProxy type) { + this.type = type; + } + + @Override + public Type getType() { + if (type != null) { + return type.get(); + } + return null; + } + + @Override + public String getTypeName() { + if (type == null) { + return typeName; + } + return type.getName(); + } + + public void setTypeName(String typeName) { + this.typeName = typeName; + } + + public TypeProxy getTypeProxy() { + return type; + } + + public void setTypeProxy(TypeProxy type) { + this.type = type; + } + + @Override + public List getGenericTypes() { + return genericTypes; + } + +} diff --git a/class-model/src/main/java/org/glassfish/hk2/classmodel/reflect/impl/TypesImpl.java b/class-model/src/main/java/org/glassfish/hk2/classmodel/reflect/impl/TypesImpl.java index 65b02dda35..b977924be8 100755 --- a/class-model/src/main/java/org/glassfish/hk2/classmodel/reflect/impl/TypesImpl.java +++ b/class-model/src/main/java/org/glassfish/hk2/classmodel/reflect/impl/TypesImpl.java @@ -38,18 +38,20 @@ public TypesImpl(TypesCtr types, URI definingURI) { this.types = types; } + @Override public Class getType(int access) { - if ((access & Opcodes.ACC_ANNOTATION)==Opcodes.ACC_ANNOTATION) { - return AnnotationType.class; - } else - if ((access & Opcodes.ACC_INTERFACE)==Opcodes.ACC_INTERFACE) { + if ((access & Opcodes.ACC_ANNOTATION) == Opcodes.ACC_ANNOTATION) { + return AnnotationType.class; + } else if ((access & Opcodes.ACC_INTERFACE) == Opcodes.ACC_INTERFACE) { return InterfaceModel.class; + } else if ((access & Opcodes.ACC_ENUM) == Opcodes.ACC_ENUM) { + return EnumType.class; } else { return ClassModel.class; } - } + @Override public TypeImpl getType(int access, String name, TypeProxy parent) { Class requestedType = getType(access); @@ -58,13 +60,14 @@ public TypeImpl getType(int access, String name, TypeProxy parent) { final Type type = typeProxy.get(); TypeImpl result; if (null == type) { - if ((access & Opcodes.ACC_ANNOTATION)==Opcodes.ACC_ANNOTATION) { - result = new AnnotationTypeImpl(name, typeProxy); - } else - if ((access & Opcodes.ACC_INTERFACE)==Opcodes.ACC_INTERFACE) { + if ((access & Opcodes.ACC_ANNOTATION) == Opcodes.ACC_ANNOTATION) { + result = new AnnotationTypeImpl(name, typeProxy); + } else if ((access & Opcodes.ACC_INTERFACE) == Opcodes.ACC_INTERFACE) { result = new InterfaceModelImpl(name, typeProxy, parent); + } else if ((access & Opcodes.ACC_ENUM) == Opcodes.ACC_ENUM) { + result = new EnumTypeImpl(name, typeProxy, parent); } else { - result = new ClassModelImpl(name, typeProxy, parent); + result = new ClassModelImpl(name, typeProxy, parent); } typeProxy.set(result); return result; @@ -79,6 +82,7 @@ public TypeImpl getType(int access, String name, TypeProxy parent) { } } + @Override public FieldModelImpl getFieldModel(String name, TypeProxy type, ExtensibleType declaringType) { return new FieldModelImpl(name, type, declaringType); } diff --git a/class-model/src/test/java/org/glassfish/hk2/classmodel/reflect/test/method/ChildAnnotation.java b/class-model/src/test/java/org/glassfish/hk2/classmodel/reflect/test/method/ChildAnnotation.java new file mode 100755 index 0000000000..c781048b6d --- /dev/null +++ b/class-model/src/test/java/org/glassfish/hk2/classmodel/reflect/test/method/ChildAnnotation.java @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2020 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0, which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * This Source Code may also be made available under the following Secondary + * Licenses when the conditions for such availability set forth in the + * Eclipse Public License v. 2.0 are satisfied: GNU General Public License, + * version 2 with the GNU Classpath Exception, which is available at + * https://www.gnu.org/software/classpath/license.html. + * + * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 + */ + +package org.glassfish.hk2.classmodel.reflect.test.method; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import static java.lang.annotation.ElementType.*; + +/** + * + * @author gaurav.gupta@payara.fish + */ +@Retention(RetentionPolicy.RUNTIME) +@Target({METHOD, FIELD, PARAMETER, TYPE}) +public @interface ChildAnnotation { + + String value() default "default"; +} diff --git a/class-model/src/test/java/org/glassfish/hk2/classmodel/reflect/test/method/Color.java b/class-model/src/test/java/org/glassfish/hk2/classmodel/reflect/test/method/Color.java new file mode 100644 index 0000000000..61ab42cbb0 --- /dev/null +++ b/class-model/src/test/java/org/glassfish/hk2/classmodel/reflect/test/method/Color.java @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2020 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0, which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * This Source Code may also be made available under the following Secondary + * Licenses when the conditions for such availability set forth in the + * Eclipse Public License v. 2.0 are satisfied: GNU General Public License, + * version 2 with the GNU Classpath Exception, which is available at + * https://www.gnu.org/software/classpath/license.html. + * + * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 + */ + +package org.glassfish.hk2.classmodel.reflect.test.method; + +/** + * + * @author gaurav.gupta@payara.fish + */ +import java.lang.annotation.Repeatable; + +@Repeatable(Colors.class) +@interface Color { + + String name(); +} diff --git a/class-model/src/test/java/org/glassfish/hk2/classmodel/reflect/test/method/Colors.java b/class-model/src/test/java/org/glassfish/hk2/classmodel/reflect/test/method/Colors.java new file mode 100644 index 0000000000..f8127f164c --- /dev/null +++ b/class-model/src/test/java/org/glassfish/hk2/classmodel/reflect/test/method/Colors.java @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2020 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0, which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * This Source Code may also be made available under the following Secondary + * Licenses when the conditions for such availability set forth in the + * Eclipse Public License v. 2.0 are satisfied: GNU General Public License, + * version 2 with the GNU Classpath Exception, which is available at + * https://www.gnu.org/software/classpath/license.html. + * + * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 + */ + +package org.glassfish.hk2.classmodel.reflect.test.method; + + +/** + * + * @author gaurav.gupta@payara.fish + */ +public @interface Colors { + + Color[] value(); +} diff --git a/class-model/src/test/java/org/glassfish/hk2/classmodel/reflect/test/method/GradientColor.java b/class-model/src/test/java/org/glassfish/hk2/classmodel/reflect/test/method/GradientColor.java new file mode 100644 index 0000000000..57be6dbac7 --- /dev/null +++ b/class-model/src/test/java/org/glassfish/hk2/classmodel/reflect/test/method/GradientColor.java @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2020 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0, which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * This Source Code may also be made available under the following Secondary + * Licenses when the conditions for such availability set forth in the + * Eclipse Public License v. 2.0 are satisfied: GNU General Public License, + * version 2 with the GNU Classpath Exception, which is available at + * https://www.gnu.org/software/classpath/license.html. + * + * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 + */ + +package org.glassfish.hk2.classmodel.reflect.test.method; + +import java.lang.annotation.Repeatable; + +/** + * + * @author gaurav.gupta@payara.fish + */ +@Repeatable(GradientColors.class) +public @interface GradientColor { + + Color[] value(); +} diff --git a/class-model/src/test/java/org/glassfish/hk2/classmodel/reflect/test/method/GradientColors.java b/class-model/src/test/java/org/glassfish/hk2/classmodel/reflect/test/method/GradientColors.java new file mode 100644 index 0000000000..904b5629f5 --- /dev/null +++ b/class-model/src/test/java/org/glassfish/hk2/classmodel/reflect/test/method/GradientColors.java @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2020 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0, which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * This Source Code may also be made available under the following Secondary + * Licenses when the conditions for such availability set forth in the + * Eclipse Public License v. 2.0 are satisfied: GNU General Public License, + * version 2 with the GNU Classpath Exception, which is available at + * https://www.gnu.org/software/classpath/license.html. + * + * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 + */ + +package org.glassfish.hk2.classmodel.reflect.test.method; + + +/** + * + * @author gaurav.gupta@payara.fish + */ +public @interface GradientColors { + + GradientColor[] value(); +} diff --git a/class-model/src/test/java/org/glassfish/hk2/classmodel/reflect/test/method/MethodTest.java b/class-model/src/test/java/org/glassfish/hk2/classmodel/reflect/test/method/MethodTest.java index 2d19899777..593f65625c 100755 --- a/class-model/src/test/java/org/glassfish/hk2/classmodel/reflect/test/method/MethodTest.java +++ b/class-model/src/test/java/org/glassfish/hk2/classmodel/reflect/test/method/MethodTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2018 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2020 Oracle and/or its affiliates. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0, which is available at @@ -13,17 +13,16 @@ * * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 */ - package org.glassfish.hk2.classmodel.reflect.test.method; import org.glassfish.hk2.classmodel.reflect.*; import org.glassfish.hk2.classmodel.reflect.test.ClassModelTestsUtils; import org.junit.Assert; import org.junit.Test; - import java.io.IOException; import java.util.Collection; -import java.util.Map; +import java.util.Iterator; +import java.util.List; /** * method related tests @@ -31,7 +30,7 @@ public class MethodTest { @Test - public void simpleTest() throws IOException, InterruptedException{ + public void simpleTest() throws IOException, InterruptedException { Types types = ClassModelTestsUtils.getTypes(); Type type = types.getBy(SomeAnnotation.class.getName()); Assert.assertTrue(type instanceof AnnotationType); @@ -39,22 +38,97 @@ public void simpleTest() throws IOException, InterruptedException{ Collection aes = annotation.allAnnotatedTypes(); // we must find our SimpleAnnotatedMethod.setFoo method Assert.assertNotNull(aes); - Assert.assertTrue(aes.size()>0); + Assert.assertTrue(aes.size() > 0); for (AnnotatedElement ae : aes) { if (ae instanceof MethodModel) { MethodModel mm = (MethodModel) ae; if ("setFoo".equals(mm.getName())) { if (mm.getDeclaringType().getName().equals(SimpleAnnotatedMethod.class.getName())) { // success - - Assert.assertEquals(mm.getAnnotations().toString(), 1, mm.getAnnotations().size()); - AnnotationModel ann = (AnnotationModel) mm.getAnnotations().iterator().next(); - Assert.assertEquals("values", 3, ann.getValues().size()); - Assert.assertEquals("aLong value", 10L, ann.getValues().get("aLong")); - Assert.assertEquals("aClass value", "java.lang.Void", ann.getValues().get("aClass")); -// Assert.assertEquals("aClassArr value", "java.lang.Void", ann.getValues().get("aClassArr")); - Assert.assertEquals("default values", 3, ann.getType().getDefaultValues().size()); - Assert.assertEquals("java.lang.Void", ann.getType().getDefaultValues().get("environment")); + + Assert.assertEquals(mm.getAnnotations().toString(), 3, mm.getAnnotations().size()); + Iterator itr = mm.getAnnotations().iterator(); + AnnotationModel someAnnotation = itr.next(); + Assert.assertEquals("values", 5, someAnnotation.getValues().size()); + Assert.assertEquals("aLong value", 10L, someAnnotation.getValues().get("aLong")); + + Assert.assertEquals("aEnum value", "ENUM1", someAnnotation.getValues().get("aEnum").toString()); + + AnnotationModel childAnnotation = (AnnotationModel) someAnnotation.getValues().get("childAnnotation"); + Assert.assertEquals("childAnnotation value", "child_value", childAnnotation.getValues().get("value")); + + Assert.assertEquals("aClass value", "java.lang.Void", someAnnotation.getValues().get("aClass")); + + List aClassArr = (List) someAnnotation.getValues().get("aClassArr"); + Assert.assertEquals("aClassArr value 1", "java.lang.Integer", aClassArr.get(0)); + Assert.assertEquals("aClassArr value 2", "java.lang.String", aClassArr.get(1)); + + Assert.assertEquals("default values", 3, someAnnotation.getType().getDefaultValues().size()); + Assert.assertEquals("java.lang.Void", someAnnotation.getType().getDefaultValues().get("environment")); + + AnnotationModel colorsRepeatable = itr.next(); + List colors = (List) colorsRepeatable.getValues().get("value"); + Assert.assertEquals("red", colors.get(0).getValues().get("name")); + Assert.assertEquals("green", colors.get(1).getValues().get("name")); + + AnnotationModel gradientColorsRepeatable = itr.next(); + List gradientColors = (List) gradientColorsRepeatable.getValues().get("value"); + + List gradientColor1 = (List) gradientColors.get(0).getValues().get("value"); + Assert.assertEquals("white", gradientColor1.get(0).getValues().get("name")); + Assert.assertEquals("black", gradientColor1.get(1).getValues().get("name")); + + List gradientColor2 = (List) gradientColors.get(1).getValues().get("value"); + Assert.assertEquals("yellow", gradientColor2.get(0).getValues().get("name")); + Assert.assertEquals("orange", gradientColor2.get(1).getValues().get("name")); + + // Parameter annotations, type and generic types check + Assert.assertEquals(5, mm.getParameters().size()); + + Parameter param1 = mm.getParameter(0); + Assert.assertEquals(1, param1.getAnnotations().size()); + AnnotationModel param1AnnotationModel = param1.getAnnotations().iterator().next(); + Assert.assertEquals("brown", param1AnnotationModel.getValues().get("name")); + Assert.assertEquals("java.lang.String", param1.getTypeName()); + Assert.assertEquals(0, param1.getGenericTypes().size()); + + Parameter param2 = mm.getParameter(1); + Assert.assertEquals(0, param2.getAnnotations().size()); + Assert.assertEquals("java.util.List", param2.getTypeName()); + Assert.assertEquals(1, param2.getGenericTypes().size()); + Assert.assertEquals("java.lang.String", param2.getGenericTypes().get(0).getTypeName()); + + Parameter param3 = mm.getParameter(2); + Assert.assertEquals(0, param3.getAnnotations().size()); + Assert.assertEquals("org.glassfish.hk2.classmodel.reflect.test.method.SampleType", param3.getTypeName()); + + List param3Generics = param3.getGenericTypes(); + Assert.assertEquals(3, param3Generics.size()); + Assert.assertEquals("java.lang.Double", param3Generics.get(0).getTypeName()); + Assert.assertEquals("java.lang.String", param3Generics.get(1).getTypeName()); + Assert.assertEquals("org.glassfish.hk2.classmodel.reflect.test.method.SampleType", param3Generics.get(2).getTypeName()); + + List param3NestedGenericTypes = param3Generics.get(2).getGenericTypes(); + Assert.assertEquals(3, param3NestedGenericTypes.size()); + Assert.assertEquals("java.lang.Short", param3NestedGenericTypes.get(0).getTypeName()); + Assert.assertEquals("java.lang.Float", param3NestedGenericTypes.get(1).getTypeName()); + Assert.assertEquals("java.lang.Long", param3NestedGenericTypes.get(2).getTypeName()); + + Parameter param4 = mm.getParameter(3); + Assert.assertEquals("int", param4.getTypeName()); + + Parameter param5 = mm.getParameter(4); + Assert.assertEquals("java.lang.Object", param5.getTypeName()); + + // Method's return type check + ParameterizedType returnType = mm.getReturnType(); + Assert.assertEquals("org.glassfish.hk2.classmodel.reflect.test.method.SampleType", returnType.getTypeName()); + List returnTypeGenerics = returnType.getGenericTypes(); + Assert.assertEquals(3, returnTypeGenerics.size()); + Assert.assertEquals("java.lang.Integer", returnTypeGenerics.get(0).getTypeName()); + Assert.assertEquals("java.lang.Character", returnTypeGenerics.get(1).getTypeName()); + Assert.assertEquals("java.lang.Boolean", returnTypeGenerics.get(2).getTypeName()); + return; } } diff --git a/class-model/src/test/java/org/glassfish/hk2/classmodel/reflect/test/method/SimpleAnnotatedMethod.java b/class-model/src/test/java/org/glassfish/hk2/classmodel/reflect/test/method/SimpleAnnotatedMethod.java index d9aa1c4790..b221be5959 100755 --- a/class-model/src/test/java/org/glassfish/hk2/classmodel/reflect/test/method/SimpleAnnotatedMethod.java +++ b/class-model/src/test/java/org/glassfish/hk2/classmodel/reflect/test/method/SimpleAnnotatedMethod.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2018 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2020 Oracle and/or its affiliates. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0, which is available at @@ -13,16 +13,42 @@ * * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 */ - package org.glassfish.hk2.classmodel.reflect.test.method; +import java.util.List; + /** * a simple class with annotated method. */ public class SimpleAnnotatedMethod { - @SomeAnnotation(aLong=10, aClass=Void.class, aClassArr={Integer.class, String.class}) - public void setFoo(String foo) { - + @SomeAnnotation( + aLong = 10, + aClass = Void.class, + aClassArr = {Integer.class, String.class}, + aEnum = SomeEnum.ENUM1, + childAnnotation = @ChildAnnotation("child_value") + ) + @Color(name = "red") + @Color(name = "green") + @GradientColor({ + @Color(name = "white"), + @Color(name = "black") + }) + @GradientColor({ + @Color(name = "yellow"), + @Color(name = "orange") + }) + public SampleType setFoo( + @Color(name = "brown") String color, + List input, + SampleType> sampleType, + int count, + Object value) { + return null; } } + +class SampleType { + +} diff --git a/class-model/src/test/java/org/glassfish/hk2/classmodel/reflect/test/method/SomeAnnotation.java b/class-model/src/test/java/org/glassfish/hk2/classmodel/reflect/test/method/SomeAnnotation.java index 0fd0fbf6b0..fa168cf767 100755 --- a/class-model/src/test/java/org/glassfish/hk2/classmodel/reflect/test/method/SomeAnnotation.java +++ b/class-model/src/test/java/org/glassfish/hk2/classmodel/reflect/test/method/SomeAnnotation.java @@ -28,10 +28,20 @@ @Retention(RetentionPolicy.RUNTIME) @Target({METHOD, FIELD, PARAMETER, TYPE}) public @interface SomeAnnotation { - String value() default "default"; - Class[] aClassArr(); - Class aClass(); - long aLong(); - int runLevel() default -1; - Class environment() default Void.class; + + SomeEnum aEnum(); + + ChildAnnotation childAnnotation(); + + String value() default "default"; + + Class[] aClassArr(); + + Class aClass(); + + long aLong(); + + int runLevel() default -1; + + Class environment() default Void.class; } diff --git a/class-model/src/test/java/org/glassfish/hk2/classmodel/reflect/test/method/SomeEnum.java b/class-model/src/test/java/org/glassfish/hk2/classmodel/reflect/test/method/SomeEnum.java new file mode 100644 index 0000000000..3ee7471807 --- /dev/null +++ b/class-model/src/test/java/org/glassfish/hk2/classmodel/reflect/test/method/SomeEnum.java @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2020 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0, which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * This Source Code may also be made available under the following Secondary + * Licenses when the conditions for such availability set forth in the + * Eclipse Public License v. 2.0 are satisfied: GNU General Public License, + * version 2 with the GNU Classpath Exception, which is available at + * https://www.gnu.org/software/classpath/license.html. + * + * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 + */ + +package org.glassfish.hk2.classmodel.reflect.test.method; + +/** + * + * @author gaurav.gupta@payara.fish + */ +public enum SomeEnum { + + ENUM1, + ENUM2; +}