--- old/make/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/MemberInfo.java 2020-04-15 18:45:00.000000000 +0530 +++ /dev/null 2020-04-15 18:45:00.000000000 +0530 @@ -1,613 +0,0 @@ -/* - * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.nashorn.internal.tools.nasgen; - -import static jdk.nashorn.internal.tools.nasgen.StringConstants.OBJECT_ARRAY_DESC; -import static jdk.nashorn.internal.tools.nasgen.StringConstants.OBJECT_DESC; -import static jdk.nashorn.internal.tools.nasgen.StringConstants.OBJ_PKG; -import static jdk.nashorn.internal.tools.nasgen.StringConstants.RUNTIME_PKG; -import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTS_PKG; -import static jdk.nashorn.internal.tools.nasgen.StringConstants.STRING_DESC; -import static jdk.nashorn.internal.tools.nasgen.StringConstants.TYPE_SYMBOL; - -import jdk.internal.org.objectweb.asm.Opcodes; -import jdk.internal.org.objectweb.asm.Type; - -/** - * Details about a Java method or field annotated with any of the field/method - * annotations from the jdk.nashorn.internal.objects.annotations package. - */ -public final class MemberInfo implements Cloneable { - // class loader of this class - private static final ClassLoader MY_LOADER = MemberInfo.class.getClassLoader(); - - /** - * The different kinds of available class annotations - */ - public static enum Kind { - - /** - * This is a script class - */ - SCRIPT_CLASS, - /** - * This is a constructor - */ - CONSTRUCTOR, - /** - * This is a function - */ - FUNCTION, - /** - * This is a getter - */ - GETTER, - /** - * This is a setter - */ - SETTER, - /** - * This is a property - */ - PROPERTY, - /** - * This is a specialized version of a function - */ - SPECIALIZED_FUNCTION, - } - - // keep in sync with jdk.nashorn.internal.objects.annotations.Attribute - static final int DEFAULT_ATTRIBUTES = 0x0; - - static final int DEFAULT_ARITY = -2; - - // the kind of the script annotation - one of the above constants - private MemberInfo.Kind kind; - // script property name - private String name; - // script property attributes - private int attributes; - // name of the java member - private String javaName; - // type descriptor of the java member - private String javaDesc; - // access bits of the Java field or method - private int javaAccess; - // initial value for static @Property fields - private Object value; - // class whose object is created to fill property value - private String initClass; - // arity of the Function or Constructor - private int arity; - - private Where where; - - private Type linkLogicClass; - - private boolean isSpecializedConstructor; - - private boolean isOptimistic; - - private boolean convertsNumericArgs; - - /** - * @return the kind - */ - public Kind getKind() { - return kind; - } - - /** - * @param kind the kind to set - */ - public void setKind(final Kind kind) { - this.kind = kind; - } - - /** - * @return the name - */ - public String getName() { - return name; - } - - /** - * @param name the name to set - */ - public void setName(final String name) { - this.name = name; - } - - /** - * Tag something as specialized constructor or not - * @param isSpecializedConstructor boolean, true if specialized constructor - */ - public void setIsSpecializedConstructor(final boolean isSpecializedConstructor) { - this.isSpecializedConstructor = isSpecializedConstructor; - } - - /** - * Check if something is a specialized constructor - * @return true if specialized constructor - */ - public boolean isSpecializedConstructor() { - return isSpecializedConstructor; - } - - /** - * Check if this is an optimistic builtin function - * @return true if optimistic builtin - */ - public boolean isOptimistic() { - return isOptimistic; - } - - /** - * Tag something as optimistic builtin or not - * @param isOptimistic boolean, true if builtin constructor - */ - public void setIsOptimistic(final boolean isOptimistic) { - this.isOptimistic = isOptimistic; - } - - /** - * Check if this function converts arguments for numeric parameters to numbers - * so it's safe to pass booleans as 0 and 1 - * @return true if it is safe to convert arguments to numbers - */ - public boolean convertsNumericArgs() { - return convertsNumericArgs; - } - - /** - * Tag this as a function that converts arguments for numeric params to numbers - * @param convertsNumericArgs if true args can be safely converted to numbers - */ - public void setConvertsNumericArgs(final boolean convertsNumericArgs) { - this.convertsNumericArgs = convertsNumericArgs; - } - - /** - * Get the SpecializedFunction guard for specializations, i.e. optimistic - * builtins - * @return specialization, null if none - */ - public Type getLinkLogicClass() { - return linkLogicClass; - } - - /** - * Set the SpecializedFunction link logic class for specializations, i.e. optimistic - * builtins - * @param linkLogicClass link logic class - */ - - public void setLinkLogicClass(final Type linkLogicClass) { - this.linkLogicClass = linkLogicClass; - } - - /** - * @return the attributes - */ - public int getAttributes() { - return attributes; - } - - /** - * @param attributes the attributes to set - */ - public void setAttributes(final int attributes) { - this.attributes = attributes; - } - - /** - * @return the javaName - */ - public String getJavaName() { - return javaName; - } - - /** - * @param javaName the javaName to set - */ - public void setJavaName(final String javaName) { - this.javaName = javaName; - } - - /** - * @return the javaDesc - */ - public String getJavaDesc() { - return javaDesc; - } - - void setJavaDesc(final String javaDesc) { - this.javaDesc = javaDesc; - } - - int getJavaAccess() { - return javaAccess; - } - - void setJavaAccess(final int access) { - this.javaAccess = access; - } - - Object getValue() { - return value; - } - - void setValue(final Object value) { - this.value = value; - } - - Where getWhere() { - return where; - } - - void setWhere(final Where where) { - this.where = where; - } - - boolean isFinal() { - return (javaAccess & Opcodes.ACC_FINAL) != 0; - } - - boolean isStatic() { - return (javaAccess & Opcodes.ACC_STATIC) != 0; - } - - boolean isStaticFinal() { - return isStatic() && isFinal(); - } - - boolean isInstanceGetter() { - return kind == Kind.GETTER && where == Where.INSTANCE; - } - - /** - * Check whether this MemberInfo is a getter that resides in the instance - * - * @return true if instance setter - */ - boolean isInstanceSetter() { - return kind == Kind.SETTER && where == Where.INSTANCE; - } - - boolean isInstanceProperty() { - return kind == Kind.PROPERTY && where == Where.INSTANCE; - } - - boolean isInstanceFunction() { - return kind == Kind.FUNCTION && where == Where.INSTANCE; - } - - boolean isPrototypeGetter() { - return kind == Kind.GETTER && where == Where.PROTOTYPE; - } - - boolean isPrototypeSetter() { - return kind == Kind.SETTER && where == Where.PROTOTYPE; - } - - boolean isPrototypeProperty() { - return kind == Kind.PROPERTY && where == Where.PROTOTYPE; - } - - boolean isPrototypeFunction() { - return kind == Kind.FUNCTION && where == Where.PROTOTYPE; - } - - boolean isConstructorGetter() { - return kind == Kind.GETTER && where == Where.CONSTRUCTOR; - } - - boolean isConstructorSetter() { - return kind == Kind.SETTER && where == Where.CONSTRUCTOR; - } - - boolean isConstructorProperty() { - return kind == Kind.PROPERTY && where == Where.CONSTRUCTOR; - } - - boolean isConstructorFunction() { - return kind == Kind.FUNCTION && where == Where.CONSTRUCTOR; - } - - boolean isConstructor() { - return kind == Kind.CONSTRUCTOR; - } - - void verify() { - switch (kind) { - case CONSTRUCTOR: { - final Type returnType = Type.getReturnType(javaDesc); - if (!isJSObjectType(returnType)) { - error("return value of a @Constructor method should be of Object type, found " + returnType); - } - final Type[] argTypes = Type.getArgumentTypes(javaDesc); - if (argTypes.length < 2) { - error("@Constructor methods should have at least 2 args"); - } - if (!argTypes[0].equals(Type.BOOLEAN_TYPE)) { - error("first argument of a @Constructor method should be of boolean type, found " + argTypes[0]); - } - if (!isJavaLangObject(argTypes[1])) { - error("second argument of a @Constructor method should be of Object type, found " + argTypes[0]); - } - - if (argTypes.length > 2) { - for (int i = 2; i < argTypes.length - 1; i++) { - if (!isJavaLangObject(argTypes[i])) { - error(i + "'th argument of a @Constructor method should be of Object type, found " + argTypes[i]); - } - } - - final String lastArgTypeDesc = argTypes[argTypes.length - 1].getDescriptor(); - final boolean isVarArg = lastArgTypeDesc.equals(OBJECT_ARRAY_DESC); - if (!lastArgTypeDesc.equals(OBJECT_DESC) && !isVarArg) { - error("last argument of a @Constructor method is neither Object nor Object[] type: " + lastArgTypeDesc); - } - - if (isVarArg && argTypes.length > 3) { - error("vararg of a @Constructor method has more than 3 arguments"); - } - } - } - break; - case FUNCTION: { - final Type returnType = Type.getReturnType(javaDesc); - if (!(isValidJSType(returnType) || Type.VOID_TYPE == returnType)) { - error("return value of a @Function method should be a valid JS type, found " + returnType); - } - final Type[] argTypes = Type.getArgumentTypes(javaDesc); - if (argTypes.length < 1) { - error("@Function methods should have at least 1 arg"); - } - if (!isJavaLangObject(argTypes[0])) { - error("first argument of a @Function method should be of Object type, found " + argTypes[0]); - } - - if (argTypes.length > 1) { - for (int i = 1; i < argTypes.length - 1; i++) { - if (!isJavaLangObject(argTypes[i])) { - error(i + "'th argument of a @Function method should be of Object type, found " + argTypes[i]); - } - } - - final String lastArgTypeDesc = argTypes[argTypes.length - 1].getDescriptor(); - final boolean isVarArg = lastArgTypeDesc.equals(OBJECT_ARRAY_DESC); - if (!lastArgTypeDesc.equals(OBJECT_DESC) && !isVarArg) { - error("last argument of a @Function method is neither Object nor Object[] type: " + lastArgTypeDesc); - } - - if (isVarArg && argTypes.length > 2) { - error("vararg @Function method has more than 2 arguments"); - } - } - } - break; - case SPECIALIZED_FUNCTION: { - final Type returnType = Type.getReturnType(javaDesc); - if (!(isValidJSType(returnType) || (isSpecializedConstructor() && Type.VOID_TYPE == returnType))) { - error("return value of a @SpecializedFunction method should be a valid JS type, found " + returnType); - } - final Type[] argTypes = Type.getArgumentTypes(javaDesc); - for (int i = 0; i < argTypes.length; i++) { - if (!isValidJSType(argTypes[i])) { - error(i + "'th argument of a @SpecializedFunction method is not valid JS type, found " + argTypes[i]); - } - } - } - break; - case GETTER: { - final Type[] argTypes = Type.getArgumentTypes(javaDesc); - if (argTypes.length != 1) { - error("@Getter methods should have one argument"); - } - if (!isJavaLangObject(argTypes[0])) { - error("first argument of a @Getter method should be of Object type, found: " + argTypes[0]); - } - - if (Type.getReturnType(javaDesc).equals(Type.VOID_TYPE)) { - error("return type of getter should not be void"); - } - } - break; - case SETTER: { - final Type[] argTypes = Type.getArgumentTypes(javaDesc); - if (argTypes.length != 2) { - error("@Setter methods should have two arguments"); - } - if (!isJavaLangObject(argTypes[0])) { - error("first argument of a @Setter method should be of Object type, found: " + argTypes[0]); - } - if (!Type.getReturnType(javaDesc).toString().equals("V")) { - error("return type of of a @Setter method should be void, found: " + Type.getReturnType(javaDesc)); - } - } - break; - case PROPERTY: { - if (where == Where.CONSTRUCTOR) { - if (isStatic()) { - if (!isFinal()) { - error("static Where.CONSTRUCTOR @Property should be final"); - } - - if (!isJSPrimitiveType(Type.getType(javaDesc))) { - error("static Where.CONSTRUCTOR @Property should be a JS primitive"); - } - } - } else if (where == Where.PROTOTYPE) { - if (isStatic()) { - if (!isFinal()) { - error("static Where.PROTOTYPE @Property should be final"); - } - - if (!isJSPrimitiveType(Type.getType(javaDesc))) { - error("static Where.PROTOTYPE @Property should be a JS primitive"); - } - } - } - } - break; - - default: - break; - } - } - - /** - * Returns if the given (internal) name of a class represents a ScriptObject subtype. - */ - public static boolean isScriptObject(final String name) { - // very crude check for ScriptObject subtype! - if (name.startsWith(OBJ_PKG + "Native") || - name.equals(OBJ_PKG + "Global") || - name.equals(OBJ_PKG + "ArrayBufferView")) { - return true; - } - - if (name.startsWith(RUNTIME_PKG)) { - final String simpleName = name.substring(name.lastIndexOf('/') + 1); - switch (simpleName) { - case "ScriptObject": - case "ScriptFunction": - case "NativeJavaPackage": - case "Scope": - return true; - } - } - - if (name.startsWith(SCRIPTS_PKG)) { - final String simpleName = name.substring(name.lastIndexOf('/') + 1); - switch (simpleName) { - case "JD": - case "JO": - return true; - } - } - - return false; - } - - private static boolean isValidJSType(final Type type) { - return isJSPrimitiveType(type) || isJSObjectType(type); - } - - private static boolean isJSPrimitiveType(final Type type) { - switch (type.getSort()) { - case Type.BOOLEAN: - case Type.INT: - case Type.DOUBLE: - return true; - default: - return type != TYPE_SYMBOL; - } - } - - private static boolean isJSObjectType(final Type type) { - return isJavaLangObject(type) || isJavaLangString(type) || isScriptObject(type); - } - - private static boolean isJavaLangObject(final Type type) { - return type.getDescriptor().equals(OBJECT_DESC); - } - - private static boolean isJavaLangString(final Type type) { - return type.getDescriptor().equals(STRING_DESC); - } - - private static boolean isScriptObject(final Type type) { - if (type.getSort() != Type.OBJECT) { - return false; - } - - return isScriptObject(type.getInternalName()); - } - - private void error(final String msg) { - throw new RuntimeException(javaName + " of type " + javaDesc + " : " + msg); - } - - /** - * @return the initClass - */ - String getInitClass() { - return initClass; - } - - /** - * @param initClass the initClass to set - */ - void setInitClass(final String initClass) { - this.initClass = initClass; - } - - @Override - protected Object clone() { - try { - return super.clone(); - } catch (final CloneNotSupportedException e) { - assert false : "clone not supported " + e; - return null; - } - } - - /** - * @return the arity - */ - int getArity() { - return arity; - } - - /** - * @param arity the arity to set - */ - void setArity(final int arity) { - this.arity = arity; - } - - String getDocumentationKey(final String objName) { - if (kind == Kind.FUNCTION) { - final StringBuilder buf = new StringBuilder(objName); - switch (where) { - case CONSTRUCTOR: - break; - case PROTOTYPE: - buf.append(".prototype"); - break; - case INSTANCE: - buf.append(".this"); - break; - } - buf.append('.'); - buf.append(name); - return buf.toString(); - } - - return null; - } -}