MemberInfo.java revision 819:e008b751c93f
1104862Sru/* 2104862Sru * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. 3114402Sru * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4104862Sru * 5104862Sru * This code is free software; you can redistribute it and/or modify it 6104862Sru * under the terms of the GNU General Public License version 2 only, as 7104862Sru * published by the Free Software Foundation. Oracle designates this 8104862Sru * particular file as subject to the "Classpath" exception as provided 9104862Sru * by Oracle in the LICENSE file that accompanied this code. 10104862Sru * 11151497Sru * This code is distributed in the hope that it will be useful, but WITHOUT 12104862Sru * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13104862Sru * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1479543Sru * version 2 for more details (a copy is included in the LICENSE file that 15104862Sru * accompanied this code). 1618099Spst * 17104862Sru * You should have received a copy of the GNU General Public License version 1818099Spst * 2 along with this work; if not, write to the Free Software Foundation, 19104862Sru * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20151497Sru * 2118099Spst * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22151497Sru * or visit www.oracle.com if you need additional information or have any 23104862Sru * questions. 24104862Sru */ 25104862Sru 26104862Srupackage jdk.nashorn.internal.tools.nasgen; 27104862Sru 28104862Sruimport static jdk.nashorn.internal.tools.nasgen.StringConstants.OBJECT_ARRAY_DESC; 29104862Sruimport static jdk.nashorn.internal.tools.nasgen.StringConstants.OBJECT_DESC; 30104862Sru 31104862Sruimport jdk.internal.org.objectweb.asm.Opcodes; 32104862Sruimport jdk.internal.org.objectweb.asm.Type; 33104862Sruimport jdk.nashorn.internal.objects.annotations.Where; 3418099Spst 35104862Sru/** 36104862Sru * Details about a Java method or field annotated with any of the field/method 37104862Sru * annotations from the jdk.nashorn.internal.objects.annotations package. 38104862Sru */ 39104862Srupublic final class MemberInfo implements Cloneable { 40151497Sru /** 41151497Sru * The different kinds of available class annotations 42151497Sru */ 43104862Sru public static enum Kind { 44104862Sru /** This is a script class */ 45104862Sru SCRIPT_CLASS, 46104862Sru /** This is a constructor */ 47104862Sru CONSTRUCTOR, 4818099Spst /** This is a function */ 49104862Sru FUNCTION, 50104862Sru /** This is a getter */ 51104862Sru GETTER, 52104862Sru /** This is a setter */ 53104862Sru SETTER, 5418099Spst /** This is a property */ 55114402Sru PROPERTY, 56114402Sru /** This is a specialized version of a function */ 57114402Sru SPECIALIZED_FUNCTION, 58114402Sru /** This is a specialized version of a constructor */ 59114402Sru SPECIALIZED_CONSTRUCTOR 60114402Sru } 61114402Sru 62114402Sru // keep in sync with jdk.nashorn.internal.objects.annotations.Attribute 63114402Sru static final int DEFAULT_ATTRIBUTES = 0x0; 64114402Sru 65114402Sru static final int DEFAULT_ARITY = -2; 66114402Sru 67114402Sru // the kind of the script annotation - one of the above constants 68114402Sru private MemberInfo.Kind kind; 69114402Sru // script property name 70114402Sru private String name; 71114402Sru // script property attributes 72114402Sru private int attributes; 73114402Sru // name of the java member 74114402Sru private String javaName; 75104862Sru // type descriptor of the java member 76114402Sru private String javaDesc; 77104862Sru // access bits of the Java field or method 78104862Sru private int javaAccess; 79114402Sru // initial value for static @Property fields 80104862Sru private Object value; 8118099Spst // class whose object is created to fill property value 82114402Sru private String initClass; 83114402Sru // arity of the Function or Constructor 84114402Sru private int arity; 85114402Sru 86114402Sru private Where where; 87114402Sru 88114402Sru /** 89114402Sru * @return the kind 90114402Sru */ 91114402Sru public Kind getKind() { 92114402Sru return kind; 93114402Sru } 94114402Sru 95114402Sru /** 96114402Sru * @param kind the kind to set 9718099Spst */ 98104862Sru public void setKind(final Kind kind) { 99104862Sru this.kind = kind; 100104862Sru } 101104862Sru 102104862Sru /** 103114402Sru * @return the name 104104862Sru */ 105104862Sru public String getName() { 106114402Sru return name; 107114402Sru } 108114402Sru 109114402Sru /** 110114402Sru * @param name the name to set 11118099Spst */ 112104862Sru public void setName(final String name) { 113114402Sru this.name = name; 114114402Sru } 115114402Sru 116114402Sru /** 117114402Sru * @return the attributes 118114402Sru */ 119114402Sru public int getAttributes() { 12018099Spst return attributes; 121104862Sru } 122114402Sru 123114402Sru /** 124104862Sru * @param attributes the attributes to set 125114402Sru */ 126114402Sru public void setAttributes(final int attributes) { 127114402Sru this.attributes = attributes; 128104862Sru } 129104862Sru 130114402Sru /** 131114402Sru * @return the javaName 132114402Sru */ 133114402Sru public String getJavaName() { 134114402Sru return javaName; 135114402Sru } 136104862Sru 137104862Sru /** 138114402Sru * @param javaName the javaName to set 139104862Sru */ 14018099Spst public void setJavaName(final String javaName) { 141114402Sru this.javaName = javaName; 14218099Spst } 143104862Sru 144114402Sru /** 145114402Sru * @return the javaDesc 146114402Sru */ 147114402Sru public String getJavaDesc() { 148114402Sru return javaDesc; 149114402Sru } 150114402Sru 151114402Sru void setJavaDesc(final String javaDesc) { 152114402Sru this.javaDesc = javaDesc; 153114402Sru } 154114402Sru 155114402Sru int getJavaAccess() { 156114402Sru return javaAccess; 157114402Sru } 158114402Sru 159114402Sru void setJavaAccess(final int access) { 160114402Sru this.javaAccess = access; 161104862Sru } 162104862Sru 163114402Sru Object getValue() { 16418099Spst return value; 16518099Spst } 166114402Sru 16718099Spst void setValue(final Object value) { 168104862Sru this.value = value; 169114402Sru } 170114402Sru 171114402Sru Where getWhere() { 172114402Sru return where; 173114402Sru } 174114402Sru 175114402Sru void setWhere(final Where where) { 176114402Sru this.where = where; 177114402Sru } 178114402Sru 179114402Sru boolean isFinal() { 180114402Sru return (javaAccess & Opcodes.ACC_FINAL) != 0; 181114402Sru } 182114402Sru 183114402Sru boolean isStatic() { 184114402Sru return (javaAccess & Opcodes.ACC_STATIC) != 0; 185114402Sru } 186104862Sru 187114402Sru boolean isStaticFinal() { 188104862Sru return isStatic() && isFinal(); 189104862Sru } 190114402Sru 191114402Sru boolean isInstanceGetter() { 192114402Sru return kind == Kind.GETTER && where == Where.INSTANCE; 193114402Sru } 194114402Sru 195114402Sru /** 196114402Sru * Check whether this MemberInfo is a getter that resides in the instance 197114402Sru * @return true if instance setter 198114402Sru */ 199114402Sru boolean isInstanceSetter() { 200114402Sru return kind == Kind.SETTER && where == Where.INSTANCE; 201114402Sru } 202114402Sru 203114402Sru boolean isInstanceProperty() { 204114402Sru return kind == Kind.PROPERTY && where == Where.INSTANCE; 205114402Sru } 206114402Sru 207114402Sru boolean isInstanceFunction() { 208114402Sru return kind == Kind.FUNCTION && where == Where.INSTANCE; 209114402Sru } 210114402Sru 211114402Sru boolean isPrototypeGetter() { 212114402Sru return kind == Kind.GETTER && where == Where.PROTOTYPE; 213114402Sru } 214114402Sru 215114402Sru boolean isPrototypeSetter() { 216114402Sru return kind == Kind.SETTER && where == Where.PROTOTYPE; 217114402Sru } 218114402Sru 219114402Sru boolean isPrototypeProperty() { 220114402Sru return kind == Kind.PROPERTY && where == Where.PROTOTYPE; 221114402Sru } 222104862Sru 223114402Sru boolean isPrototypeFunction() { 224104862Sru return kind == Kind.FUNCTION && where == Where.PROTOTYPE; 225114402Sru } 22618099Spst 22718099Spst boolean isConstructorGetter() { 228114402Sru return kind == Kind.GETTER && where == Where.CONSTRUCTOR; 229114402Sru } 230114402Sru 231114402Sru boolean isConstructorSetter() { 232114402Sru return kind == Kind.SETTER && where == Where.CONSTRUCTOR; 233114402Sru } 234114402Sru 235114402Sru boolean isConstructorProperty() { 236114402Sru return kind == Kind.PROPERTY && where == Where.CONSTRUCTOR; 237114402Sru } 238114402Sru 239114402Sru boolean isConstructorFunction() { 240114402Sru return kind == Kind.FUNCTION && where == Where.CONSTRUCTOR; 241114402Sru } 242114402Sru 243114402Sru boolean isConstructor() { 244114402Sru return kind == Kind.CONSTRUCTOR; 245114402Sru } 246114402Sru 247114402Sru void verify() { 248114402Sru if (kind == Kind.CONSTRUCTOR) { 249114402Sru final Type returnType = Type.getReturnType(javaDesc); 250114402Sru if (! returnType.toString().equals(OBJECT_DESC)) { 251114402Sru error("return value should be of Object type, found " + returnType); 252114402Sru } 253114402Sru final Type[] argTypes = Type.getArgumentTypes(javaDesc); 254114402Sru if (argTypes.length < 2) { 255114402Sru error("constructor methods should have at least 2 args"); 256114402Sru } 257114402Sru if (! argTypes[0].equals(Type.BOOLEAN_TYPE)) { 258114402Sru error("first argument should be of boolean type, found " + argTypes[0]); 259114402Sru } 260114402Sru if (! argTypes[1].toString().equals(OBJECT_DESC)) { 261114402Sru error("second argument should be of Object type, found " + argTypes[0]); 262114402Sru } 263114402Sru 264114402Sru if (argTypes.length > 2) { 265114402Sru for (int i = 2; i < argTypes.length - 1; i++) { 266114402Sru if (! argTypes[i].toString().equals(OBJECT_DESC)) { 267114402Sru error(i + "'th argument should be of Object type, found " + argTypes[i]); 268114402Sru } 269114402Sru } 270114402Sru 271114402Sru final String lastArgType = argTypes[argTypes.length - 1].toString(); 272114402Sru final boolean isVarArg = lastArgType.equals(OBJECT_ARRAY_DESC); 273114402Sru if (!lastArgType.equals(OBJECT_DESC) && !isVarArg) { 274114402Sru error("last argument is neither Object nor Object[] type: " + lastArgType); 275114402Sru } 276114402Sru 277114402Sru if (isVarArg && argTypes.length > 3) { 278114402Sru error("vararg constructor has more than 3 arguments"); 279114402Sru } 280114402Sru } 281114402Sru } else if (kind == Kind.FUNCTION) { 282114402Sru final Type[] argTypes = Type.getArgumentTypes(javaDesc); 283114402Sru if (argTypes.length < 1) { 284114402Sru error("function methods should have at least 1 arg"); 28518099Spst } 286104862Sru if (! argTypes[0].toString().equals(OBJECT_DESC)) { 287104862Sru error("first argument should be of Object type, found " + argTypes[0]); 288104862Sru } 289114402Sru 29018099Spst if (argTypes.length > 1) { 29118099Spst for (int i = 1; i < argTypes.length - 1; i++) { 292114402Sru if (! argTypes[i].toString().equals(OBJECT_DESC)) { 293114402Sru error(i + "'th argument should be of Object type, found " + argTypes[i]); 294114402Sru } 295114402Sru } 29618099Spst 297114402Sru final String lastArgType = argTypes[argTypes.length - 1].toString(); 298114402Sru final boolean isVarArg = lastArgType.equals(OBJECT_ARRAY_DESC); 299114402Sru if (!lastArgType.equals(OBJECT_DESC) && !isVarArg) { 300114402Sru error("last argument is neither Object nor Object[] type: " + lastArgType); 301114402Sru } 302114402Sru 303114402Sru if (isVarArg && argTypes.length > 2) { 304114402Sru error("vararg function has more than 2 arguments"); 305114402Sru } 306114402Sru } 307114402Sru } else if (kind == Kind.GETTER) { 308114402Sru final Type[] argTypes = Type.getArgumentTypes(javaDesc); 309114402Sru if (argTypes.length != 1) { 310114402Sru error("getter methods should have one argument"); 311114402Sru } 312114402Sru if (! argTypes[0].toString().equals(OBJECT_DESC)) { 313114402Sru error("first argument of getter should be of Object type, found: " + argTypes[0]); 314114402Sru } 315114402Sru if (Type.getReturnType(javaDesc).equals(Type.VOID_TYPE)) { 316114402Sru error("return type of getter should not be void"); 317114402Sru } 318114402Sru } else if (kind == Kind.SETTER) { 319114402Sru final Type[] argTypes = Type.getArgumentTypes(javaDesc); 320114402Sru if (argTypes.length != 2) { 321114402Sru error("setter methods should have two arguments"); 322114402Sru } 323114402Sru if (! argTypes[0].toString().equals(OBJECT_DESC)) { 324114402Sru error("first argument of setter should be of Object type, found: " + argTypes[0]); 325114402Sru } 326114402Sru if (!Type.getReturnType(javaDesc).toString().equals("V")) { 327114402Sru error("return type of setter should be void, found: " + Type.getReturnType(javaDesc)); 328114402Sru } 329114402Sru } 330114402Sru } 331114402Sru 332114402Sru private void error(final String msg) { 333114402Sru throw new RuntimeException(javaName + javaDesc + " : " + msg); 334114402Sru } 335114402Sru 336114402Sru /** 337114402Sru * @return the initClass 33818099Spst */ 339104862Sru String getInitClass() { 340104862Sru return initClass; 341114402Sru } 34218099Spst 343114402Sru /** 344114402Sru * @param initClass the initClass to set 34518099Spst */ 346104862Sru void setInitClass(final String initClass) { 347114402Sru this.initClass = initClass; 348114402Sru } 349114402Sru 35018099Spst @Override 351104862Sru protected Object clone() { 352114402Sru try { 353114402Sru return super.clone(); 354104862Sru } catch (final CloneNotSupportedException e) { 355104862Sru assert false : "clone not supported " + e; 356104862Sru return null; 357104862Sru } 358104862Sru } 359104862Sru 360114402Sru /** 361104862Sru * @return the arity 362114402Sru */ 363104862Sru int getArity() { 364104862Sru return arity; 365104862Sru } 366104862Sru 367104862Sru /** 368104862Sru * @param arity the arity to set 369114402Sru */ 370114402Sru void setArity(final int arity) { 371114402Sru this.arity = arity; 372114402Sru } 373104862Sru} 374104862Sru