예제 #1
0
  public MethodInfo findSuperclassImplementation(HashSet notStrippable) {
    if (mReturnType == null) {
      // ctor
      return null;
    }
    if (mOverriddenMethod != null) {
      // Even if we're told outright that this was the overridden method, we want to
      // be conservative and ignore mismatches of parameter types -- they arise from
      // extending generic specializations, and we want to consider the derived-class
      // method to be a non-override.
      if (this.signature().equals(mOverriddenMethod.signature())) {
        return mOverriddenMethod;
      }
    }

    ArrayList<ClassInfo> queue = new ArrayList<ClassInfo>();
    if (containingClass().realSuperclass() != null
        && containingClass().realSuperclass().isAbstract()) {
      queue.add(containingClass());
    }
    addInterfaces(containingClass().realInterfaces(), queue);
    for (ClassInfo iface : queue) {
      for (MethodInfo me : iface.methods()) {
        if (me.name().equals(this.name())
            && me.signature().equals(this.signature())
            && notStrippable.contains(me.containingClass())) {
          return me;
        }
      }
    }
    return null;
  }
예제 #2
0
  public MethodInfo findRealOverriddenMethod(String name, String signature, HashSet notStrippable) {
    if (mReturnType == null) {
      // ctor
      return null;
    }
    if (mOverriddenMethod != null) {
      return mOverriddenMethod;
    }

    ArrayList<ClassInfo> queue = new ArrayList<ClassInfo>();
    if (containingClass().realSuperclass() != null
        && containingClass().realSuperclass().isAbstract()) {
      queue.add(containingClass());
    }
    addInterfaces(containingClass().realInterfaces(), queue);
    for (ClassInfo iface : queue) {
      for (MethodInfo me : iface.methods()) {
        if (me.name().equals(name)
            && me.signature().equals(signature)
            && me.inlineTags().tags() != null
            && me.inlineTags().tags().length > 0
            && notStrippable.contains(me.containingClass())) {
          return me;
        }
      }
    }
    return null;
  }
예제 #3
0
 public boolean throwsException(ClassInfo exception) {
   for (ClassInfo e : mThrownExceptions) {
     if (e.qualifiedName().equals(exception.qualifiedName())) {
       return true;
     }
   }
   return false;
 }
예제 #4
0
 private static void addInterfaces(ArrayList<ClassInfo> ifaces, ArrayList<ClassInfo> queue) {
   for (ClassInfo i : ifaces) {
     queue.add(i);
   }
   for (ClassInfo i : ifaces) {
     addInterfaces(i.interfaces(), queue);
   }
 }
예제 #5
0
 public boolean isEffectivelyFinal() {
   if (mIsFinal) {
     return true;
   }
   ClassInfo containingClass = containingClass();
   if (containingClass != null && containingClass.isEffectivelyFinal()) {
     return true;
   }
   return false;
 }
예제 #6
0
 private boolean inList(ClassInfo item, ThrowsTagInfo[] list) {
   int len = list.length;
   String qn = item.qualifiedName();
   for (int i = 0; i < len; i++) {
     ClassInfo ex = list[i].exception();
     if (ex != null && ex.qualifiedName().equals(qn)) {
       return true;
     }
   }
   return false;
 }
예제 #7
0
 public HashSet<String> typeVariables() {
   HashSet<String> result = TypeInfo.typeVariables(mTypeParameters);
   ClassInfo cl = containingClass();
   while (cl != null) {
     ArrayList<TypeInfo> types = cl.asTypeInfo().typeArguments();
     if (types != null) {
       TypeInfo.typeVariables(types, result);
     }
     cl = cl.containingClass();
   }
   return result;
 }
 /**
  * Sets a handle internally used to create MetaClass implementations. When replacing the handle
  * with a custom version, you should reuse the old handle to keep custom logic and to use the
  * default logic as fall back. WARNING: experimental code, likely to change soon
  *
  * @param handle the handle
  */
 public void setMetaClassCreationHandle(MetaClassCreationHandle handle) {
   if (handle == null)
     throw new IllegalArgumentException("Cannot set MetaClassCreationHandle to null value!");
   ClassInfo.clearModifiedExpandos();
   handle.setDisableCustomMetaClassLookup(
       metaClassCreationHandle.isDisableCustomMetaClassLookup());
   metaClassCreationHandle = handle;
 }
예제 #9
0
  private void initializeBeanResults(ResultSet rs) {
    try {
      ClassInfo classInfo = ClassInfo.getInstance(getResultClass());
      String[] propertyNames = classInfo.getWriteablePropertyNames();

      Map propertyMap = new HashMap();
      for (int i = 0; i < propertyNames.length; i++) {
        propertyMap.put(propertyNames[i].toUpperCase(java.util.Locale.ENGLISH), propertyNames[i]);
      }

      List resultMappingList = new ArrayList();
      ResultSetMetaData rsmd = rs.getMetaData();
      for (int i = 0, n = rsmd.getColumnCount(); i < n; i++) {
        String columnName = getColumnIdentifier(rsmd, i + 1);
        String upperColumnName = columnName.toUpperCase(java.util.Locale.ENGLISH);
        String matchedProp = (String) propertyMap.get(upperColumnName);
        Class type = null;
        if (matchedProp == null) {
          Probe p = ProbeFactory.getProbe(this.getResultClass());
          try {
            type = p.getPropertyTypeForSetter(this.getResultClass(), columnName);
          } catch (Exception e) {
            // TODO - add logging to this class?
          }
        } else {
          type = classInfo.getSetterType(matchedProp);
        }
        if (type != null || matchedProp != null) {
          ResultMapping resultMapping = new ResultMapping();
          resultMapping.setPropertyName((matchedProp != null ? matchedProp : columnName));
          resultMapping.setColumnName(columnName);
          resultMapping.setColumnIndex(i + 1);
          resultMapping.setTypeHandler(
              getDelegate().getTypeHandlerFactory().getTypeHandler(type)); // map SQL to JDBC type
          resultMappingList.add(resultMapping);
        }
      }
      setResultMappingList(resultMappingList);

    } catch (SQLException e) {
      throw new RuntimeException("Error automapping columns. Cause: " + e);
    }
  }
  public MetaClassRegistryImpl(final int loadDefault, final boolean useAccessible) {
    this.useAccessible = useAccessible;

    if (loadDefault == LOAD_DEFAULT) {
      Map<CachedClass, List<MetaMethod>> map = new HashMap<CachedClass, List<MetaMethod>>();

      // let's register the default methods
      registerMethods(null, true, true, map);
      final Class[] additionals = DefaultGroovyMethods.additionals;
      for (int i = 0; i != additionals.length; ++i) {
        createMetaMethodFromClass(map, additionals[i]);
      }

      Class[] pluginDGMs = VMPluginFactory.getPlugin().getPluginDefaultGroovyMethods();
      for (Class plugin : pluginDGMs) {
        registerMethods(plugin, false, true, map);
      }
      registerMethods(DefaultGroovyStaticMethods.class, false, false, map);
      Class[] staticPluginDGMs = VMPluginFactory.getPlugin().getPluginStaticGroovyMethods();
      for (Class plugin : staticPluginDGMs) {
        registerMethods(plugin, false, false, map);
      }

      for (Map.Entry<CachedClass, List<MetaMethod>> e : map.entrySet()) {
        CachedClass cls = e.getKey();
        cls.setNewMopMethods(e.getValue());
      }
    }

    installMetaClassCreationHandle();

    final MetaClass emcMetaClass = metaClassCreationHandle.create(ExpandoMetaClass.class, this);
    emcMetaClass.initialize();
    ClassInfo.getClassInfo(ExpandoMetaClass.class).setStrongMetaClass(emcMetaClass);

    addMetaClassRegistryChangeEventListener(
        new MetaClassRegistryChangeEventListener() {
          public void updateConstantMetaClass(MetaClassRegistryChangeEvent cmcu) {
            synchronized (metaClassInfo) {
              metaClassInfo.add(cmcu.getNewMetaClass());
              DefaultMetaClassInfo.getNewConstantMetaClassVersioning();
              Class c = cmcu.getClassToUpdate();
              DefaultMetaClassInfo.setPrimitiveMeta(c, cmcu.getNewMetaClass() == null);
              Field sdyn;
              try {
                sdyn = c.getDeclaredField(Verifier.STATIC_METACLASS_BOOL);
                sdyn.setBoolean(null, cmcu.getNewMetaClass() != null);
              } catch (Throwable e) {
                // DO NOTHING
              }
            }
          }
        });
  }
예제 #11
0
  public ThrowsTagInfo[] throwsTags() {
    if (mThrowsTags == null) {
      ThrowsTagInfo[] documented = comment().throwsTags();
      ArrayList<ThrowsTagInfo> rv = new ArrayList<ThrowsTagInfo>();

      int len = documented.length;
      for (int i = 0; i < len; i++) {
        rv.add(documented[i]);
      }

      for (ClassInfo cl : mThrownExceptions) {
        if (documented == null || !inList(cl, documented)) {
          rv.add(
              new ThrowsTagInfo(
                  "@throws", "@throws", cl.qualifiedName(), cl, "", containingClass(), position()));
        }
      }
      mThrowsTags = rv.toArray(new ThrowsTagInfo[rv.size()]);
    }
    return mThrowsTags;
  }
예제 #12
0
  // first looks for a superclass, and then does a breadth first search to
  // find the least far away match
  public MethodInfo findOverriddenMethod(String name, String signature) {
    if (mReturnType == null) {
      // ctor
      return null;
    }
    if (mOverriddenMethod != null) {
      return mOverriddenMethod;
    }

    ArrayList<ClassInfo> queue = new ArrayList<ClassInfo>();
    addInterfaces(containingClass().interfaces(), queue);
    for (ClassInfo iface : queue) {
      for (MethodInfo me : iface.methods()) {
        if (me.name().equals(name)
            && me.signature().equals(signature)
            && me.inlineTags().tags() != null
            && me.inlineTags().tags().length > 0) {
          return me;
        }
      }
    }
    return null;
  }
예제 #13
0
 private static void addRealInterfaces(ArrayList<ClassInfo> ifaces, ArrayList<ClassInfo> queue) {
   for (ClassInfo i : ifaces) {
     queue.add(i);
     if (i.realSuperclass() != null && i.realSuperclass().isAbstract()) {
       queue.add(i.superclass());
     }
   }
   for (ClassInfo i : ifaces) {
     addInterfaces(i.realInterfaces(), queue);
   }
 }
  public void setMetaClass(Object obj, MetaClass theMetaClass) {
    Class theClass = obj.getClass();
    final ClassInfo info = ClassInfo.getClassInfo(theClass);
    MetaClass oldMC = null;
    info.lock();
    try {
      oldMC = info.getPerInstanceMetaClass(obj);
      info.setPerInstanceMetaClass(obj, theMetaClass);
    } finally {
      info.unlock();
    }

    fireConstantMetaClassUpdate(obj, theClass, oldMC, theMetaClass);
  }
  /**
   * if oldMc is null, newMc will replace whatever meta class was used before. if oldMc is not null,
   * then newMc will be used only if he stored mc is the same as oldMc
   */
  private void setMetaClass(Class theClass, MetaClass oldMc, MetaClass newMc) {
    final ClassInfo info = ClassInfo.getClassInfo(theClass);

    MetaClass mc = null;
    info.lock();
    try {
      mc = info.getStrongMetaClass();
      info.setStrongMetaClass(newMc);
    } finally {
      info.unlock();
    }
    if ((oldMc == null && mc != newMc) || (oldMc != null && mc != newMc && mc != oldMc)) {
      fireConstantMetaClassUpdate(null, theClass, mc, newMc);
    }
  }
  public void generate(
      ClassInfo info, Class superclassType, Property[] props, Class[] propTypes, IndentedWriter iw)
      throws IOException {
    iw.print(CodegenUtils.getModifierString(ctor_modifiers));
    iw.print(' ' + info.getClassName() + "( Map map )");
    iw.println("{");
    iw.upIndent();

    iw.println("Object raw;");
    for (int i = 0, len = props.length; i < len; ++i) {
      Property prop = props[i];
      String propName = prop.getName();
      Class propType = propTypes[i];
      iw.println("raw = map.get( \"" + propName + "\" );");
      iw.println("if (raw != null)");
      iw.println("{");
      iw.upIndent();

      iw.print("this." + propName + " = ");
      if (propType == boolean.class) iw.println("((Boolean) raw ).booleanValue();");
      else if (propType == byte.class) iw.println("((Byte) raw ).byteValue();");
      else if (propType == char.class) iw.println("((Character) raw ).charValue();");
      else if (propType == short.class) iw.println("((Short) raw ).shortValue();");
      else if (propType == int.class) iw.println("((Integer) raw ).intValue();");
      else if (propType == long.class) iw.println("((Long) raw ).longValue();");
      else if (propType == float.class) iw.println("((Float) raw ).floatValue();");
      else if (propType == double.class) iw.println("((Double) raw ).doubleValue();");
      iw.println("raw = null;");

      iw.downIndent();
      iw.println("}");
    }

    iw.downIndent();
    iw.println("}");
  }
  //
  // Visitor generation methods
  //
  public void generateDepthFirstVisitor() throws FileExistsException {
    try {
      File file = new File(visitorDir, outFilename);

      if (Globals.noOverwrite && file.exists()) throw new FileExistsException(outFilename);

      PrintWriter out = new PrintWriter(new FileOutputStream(file), false);
      Spacing spc = new Spacing(INDENT_AMT);

      out.println(Globals.fileHeader(spc));
      out.println();
      out.println(spc.spc + "package " + Globals.visitorPackage + ";");
      if (!Globals.visitorPackage.equals(Globals.nodePackage))
        out.println(spc.spc + "import " + Globals.nodePackage + ".*;");
      out.println(spc.spc + "import java.util.*;\n");
      out.println(spc.spc + "/**");
      out.println(
          spc.spc
              + " * Provides default methods which visit each "
              + "node in the tree in depth-first");
      out.println(spc.spc + " * order.  Your visitors may extend this class.");
      out.println(spc.spc + " */");
      out.println(
          spc.spc
              + "public class "
              + visitorName
              + "<R,A> implements "
              + Globals.GJVisitorName
              + "<R,A> {");
      printAutoVisitorMethods(out);

      spc.updateSpc(+1);
      out.println(spc.spc + "//");
      out.println(spc.spc + "// User-generated visitor methods below");
      out.println(spc.spc + "//");
      out.println();

      for (Enumeration e = classList.elements(); e.hasMoreElements(); ) {
        ClassInfo cur = (ClassInfo) e.nextElement();
        String name = cur.getName();

        out.println(spc.spc + "/**");
        if (Globals.javaDocComments) out.println(spc.spc + " * <PRE>");
        out.println(cur.getEbnfProduction(spc));
        if (Globals.javaDocComments) out.println(spc.spc + " * </PRE>");
        out.println(spc.spc + " */");
        out.print(spc.spc + "public R visit");
        out.println("(" + name + " n, A argu) {");

        spc.updateSpc(+1);
        out.println(spc.spc + "R _ret=null;");
        for (Enumeration f = cur.getNameList().elements(); f.hasMoreElements(); )
          out.println(spc.spc + "n." + (String) f.nextElement() + ".accept(this, argu);");
        out.println(spc.spc + "return _ret;");
        spc.updateSpc(-1);
        out.println(spc.spc + "}\n");
      }

      spc.updateSpc(-1);
      out.println(spc.spc + "}");

      out.flush();
      out.close();
    } catch (IOException e) {
      Errors.hardErr("Could not generate " + outFilename);
    }
  }
 public MetaClass getMetaClass(Object obj) {
   return ClassInfo.getClassInfo(obj.getClass()).getMetaClass(obj);
 }
예제 #19
0
  public boolean isConsistent(MethodInfo mInfo) {
    boolean consistent = true;
    if (this.mReturnType != mInfo.mReturnType && !this.mReturnType.equals(mInfo.mReturnType)) {
      if (!mReturnType.isPrimitive() && !mInfo.mReturnType.isPrimitive()) {
        // Check to see if our class extends the old class.
        ApiInfo infoApi = mInfo.containingClass().containingPackage().containingApi();
        ClassInfo infoReturnClass = infoApi.findClass(mInfo.mReturnType.qualifiedTypeName());
        // Find the classes.
        consistent =
            infoReturnClass != null
                && infoReturnClass.isAssignableTo(mReturnType.qualifiedTypeName());
      } else {
        consistent = false;
      }

      if (!consistent) {
        Errors.error(
            Errors.CHANGED_TYPE,
            mInfo.position(),
            "Method "
                + mInfo.qualifiedName()
                + " has changed return type from "
                + mReturnType
                + " to "
                + mInfo.mReturnType);
      }
    }

    if (mIsAbstract != mInfo.mIsAbstract) {
      consistent = false;
      Errors.error(
          Errors.CHANGED_ABSTRACT,
          mInfo.position(),
          "Method " + mInfo.qualifiedName() + " has changed 'abstract' qualifier");
    }

    if (mIsNative != mInfo.mIsNative) {
      consistent = false;
      Errors.error(
          Errors.CHANGED_NATIVE,
          mInfo.position(),
          "Method " + mInfo.qualifiedName() + " has changed 'native' qualifier");
    }

    if (!mIsStatic) {
      // Compiler-generated methods vary in their 'final' qualifier between versions of
      // the compiler, so this check needs to be quite narrow. A change in 'final'
      // status of a method is only relevant if (a) the method is not declared 'static'
      // and (b) the method is not already inferred to be 'final' by virtue of its class.
      if (!isEffectivelyFinal() && mInfo.isEffectivelyFinal()) {
        consistent = false;
        Errors.error(
            Errors.ADDED_FINAL,
            mInfo.position(),
            "Method " + mInfo.qualifiedName() + " has added 'final' qualifier");
      } else if (isEffectivelyFinal() && !mInfo.isEffectivelyFinal()) {
        consistent = false;
        Errors.error(
            Errors.REMOVED_FINAL,
            mInfo.position(),
            "Method " + mInfo.qualifiedName() + " has removed 'final' qualifier");
      }
    }

    if (mIsStatic != mInfo.mIsStatic) {
      consistent = false;
      Errors.error(
          Errors.CHANGED_STATIC,
          mInfo.position(),
          "Method " + mInfo.qualifiedName() + " has changed 'static' qualifier");
    }

    if (!scope().equals(mInfo.scope())) {
      consistent = false;
      Errors.error(
          Errors.CHANGED_SCOPE,
          mInfo.position(),
          "Method "
              + mInfo.qualifiedName()
              + " changed scope from "
              + scope()
              + " to "
              + mInfo.scope());
    }

    if (!isDeprecated() == mInfo.isDeprecated()) {
      Errors.error(
          Errors.CHANGED_DEPRECATED,
          mInfo.position(),
          "Method "
              + mInfo.qualifiedName()
              + " has changed deprecation state "
              + isDeprecated()
              + " --> "
              + mInfo.isDeprecated());
      consistent = false;
    }

    // see JLS 3 13.4.20 "Adding or deleting a synchronized modifier of a method does not break "
    // "compatibility with existing binaries."
    /*
    if (mIsSynchronized != mInfo.mIsSynchronized) {
      Errors.error(Errors.CHANGED_SYNCHRONIZED, mInfo.position(), "Method " + mInfo.qualifiedName()
          + " has changed 'synchronized' qualifier from " + mIsSynchronized + " to "
          + mInfo.mIsSynchronized);
      consistent = false;
    }
    */

    for (ClassInfo exception : thrownExceptions()) {
      if (!mInfo.throwsException(exception)) {
        // exclude 'throws' changes to finalize() overrides with no arguments
        if (!name().equals("finalize") || (!mParameters.isEmpty())) {
          Errors.error(
              Errors.CHANGED_THROWS,
              mInfo.position(),
              "Method "
                  + mInfo.qualifiedName()
                  + " no longer throws exception "
                  + exception.qualifiedName());
          consistent = false;
        }
      }
    }

    for (ClassInfo exec : mInfo.thrownExceptions()) {
      // exclude 'throws' changes to finalize() overrides with no arguments
      if (!throwsException(exec)) {
        if (!name().equals("finalize") || (!mParameters.isEmpty())) {
          Errors.error(
              Errors.CHANGED_THROWS,
              mInfo.position(),
              "Method "
                  + mInfo.qualifiedName()
                  + " added thrown exception "
                  + exec.qualifiedName());
          consistent = false;
        }
      }
    }

    return consistent;
  }
예제 #20
0
  public MethodInfo(
      String rawCommentText,
      ArrayList<TypeInfo> typeParameters,
      String name,
      String signature,
      ClassInfo containingClass,
      ClassInfo realContainingClass,
      boolean isPublic,
      boolean isProtected,
      boolean isPackagePrivate,
      boolean isPrivate,
      boolean isFinal,
      boolean isStatic,
      boolean isSynthetic,
      boolean isAbstract,
      boolean isSynchronized,
      boolean isNative,
      boolean isAnnotationElement,
      String kind,
      String flatSignature,
      MethodInfo overriddenMethod,
      TypeInfo returnType,
      ArrayList<ParameterInfo> parameters,
      ArrayList<ClassInfo> thrownExceptions,
      SourcePositionInfo position,
      ArrayList<AnnotationInstanceInfo> annotations) {
    // Explicitly coerce 'final' state of Java6-compiled enum values() method, to match
    // the Java5-emitted base API description.
    super(
        rawCommentText,
        name,
        signature,
        containingClass,
        realContainingClass,
        isPublic,
        isProtected,
        isPackagePrivate,
        isPrivate,
        ((name.equals("values") && containingClass.isEnum()) ? true : isFinal),
        isStatic,
        isSynthetic,
        kind,
        position,
        annotations);

    // The underlying MethodDoc for an interface's declared methods winds up being marked
    // non-abstract. Correct that here by looking at the immediate-parent class, and marking
    // this method abstract if it is an unimplemented interface method.
    if (containingClass.isInterface()) {
      isAbstract = true;
    }

    mReasonOpened = "0:0";
    mIsAnnotationElement = isAnnotationElement;
    mTypeParameters = typeParameters;
    mIsAbstract = isAbstract;
    mIsSynchronized = isSynchronized;
    mIsNative = isNative;
    mFlatSignature = flatSignature;
    mOverriddenMethod = overriddenMethod;
    mReturnType = returnType;
    mParameters = parameters;
    mThrownExceptions = thrownExceptions;
  }
 public final MetaClass getMetaClass(Class theClass) {
   return ClassInfo.getClassInfo(theClass).getMetaClass();
 }