Beispiel #1
0
  @Override
  protected IMethod[] getDeclaredIMethods2() {
    List<IMethod> iMethods = new ArrayList();

    for (ClassFile.MethodInfo mi : this.classFile.methodInfos) {

      // Skip JDK 1.5 synthetic methods (e.g. those generated for
      // covariant return values).
      if (Mod.isSynthetic(mi.getModifierFlags())) continue;

      IInvocable ii;
      try {
        ii = this.resolveMethod(mi);
      } catch (ClassNotFoundException ex) {
        throw new JaninoRuntimeException(ex.getMessage(), ex);
      }
      if (ii instanceof IMethod) iMethods.add((IMethod) ii);
    }

    return (IMethod[]) iMethods.toArray(new IMethod[iMethods.size()]);
  }
Beispiel #2
0
  /**
   * Turn a {@link ClassFile.MethodInfo} into an {@link IInvocable}. This includes the checking and
   * the removal of the magic first parameter of an inner class constructor.
   *
   * @param methodInfo
   * @throws ClassNotFoundException
   */
  private IInvocable resolveMethod(final ClassFile.MethodInfo methodInfo)
      throws ClassNotFoundException {
    IInvocable result = (IInvocable) this.resolvedMethods.get(methodInfo);
    if (result != null) return result;

    // Determine method name.
    final String name = methodInfo.getName();

    // Determine return type.
    MethodDescriptor md = new MethodDescriptor(methodInfo.getDescriptor());

    final IClass returnType = this.resolveClass(md.returnFd);

    // Determine parameter types.
    final IClass[] parameterTypes = new IClass[md.parameterFds.length];
    for (int i = 0; i < parameterTypes.length; ++i)
      parameterTypes[i] = this.resolveClass(md.parameterFds[i]);

    // Determine thrown exceptions.
    IClass[] tes = null;
    ClassFile.AttributeInfo[] ais = methodInfo.getAttributes();
    for (ClassFile.AttributeInfo ai : ais) {
      if (ai instanceof ClassFile.ExceptionsAttribute) {
        ConstantClassInfo[] ccis =
            ((ClassFile.ExceptionsAttribute) ai).getExceptions(this.classFile);
        tes = new IClass[ccis.length];
        for (int i = 0; i < tes.length; ++i) {
          tes[i] = this.resolveClass(Descriptor.fromInternalForm(ccis[i].getName(this.classFile)));
        }
      }
    }
    final IClass[] thrownExceptions = tes == null ? new IClass[0] : tes;

    // Determine access.
    final Access access = ClassFileIClass.accessFlags2Access(methodInfo.getModifierFlags());

    if ("<init>".equals(name)) {
      result =
          new IClass.IConstructor() {

            @Override
            public boolean isVarargs() {
              return Mod.isVarargs(methodInfo.getModifierFlags());
            }

            @Override
            public IClass[] getParameterTypes2() throws CompileException {

              // Process magic first parameter of inner class constructor.
              IClass outerIClass = ClassFileIClass.this.getOuterIClass();
              if (outerIClass != null) {
                if (parameterTypes.length < 1) {
                  throw new JaninoRuntimeException(
                      "Inner class constructor lacks magic first parameter");
                }
                if (parameterTypes[0] != outerIClass) {
                  throw new JaninoRuntimeException(
                      "Magic first parameter of inner class constructor has type \""
                          + parameterTypes[0].toString()
                          + "\" instead of that of its enclosing instance (\""
                          + outerIClass.toString()
                          + "\")");
                }
                IClass[] tmp = new IClass[parameterTypes.length - 1];
                System.arraycopy(parameterTypes, 1, tmp, 0, tmp.length);
                return tmp;
              }

              return parameterTypes;
            }

            @Override
            public IClass[] getThrownExceptions2() {
              return thrownExceptions;
            }

            @Override
            public Access getAccess() {
              return access;
            }

            @Override
            public Java.Annotation[] getAnnotations() {
              return methodInfo.getAnnotations();
            }
          };
    } else {
      result =
          new IClass.IMethod() {

            @Override
            public String getName() {
              return name;
            }

            @Override
            public IClass getReturnType() {
              return returnType;
            }

            @Override
            public boolean isStatic() {
              return Mod.isStatic(methodInfo.getModifierFlags());
            }

            @Override
            public boolean isAbstract() {
              return Mod.isAbstract(methodInfo.getModifierFlags());
            }

            @Override
            public boolean isVarargs() {
              return Mod.isVarargs(methodInfo.getModifierFlags());
            }

            @Override
            public IClass[] getParameterTypes2() {
              return parameterTypes;
            }

            @Override
            public IClass[] getThrownExceptions2() {
              return thrownExceptions;
            }

            @Override
            public Access getAccess() {
              return access;
            }

            @Override
            public Java.Annotation[] getAnnotations() {
              return methodInfo.getAnnotations();
            }
          };
    }
    this.resolvedMethods.put(methodInfo, result);
    return result;
  }