📄 referencevalue.java
字号:
if (thisReferencedClass != null && otherReferencedClass != null) { if (thisReferencedClass.extendsOrImplements(otherReferencedClass)) { return other.generalizeMayBeNull(mayBeNull); } if (otherReferencedClass.extendsOrImplements(thisReferencedClass)) { return this.generalizeMayBeNull(mayBeNull); } // Collect the super classes and interfaces of this class. Set thisSuperClasses = new HashSet(); thisReferencedClass.hierarchyAccept(false, true, true, false, new ClassCollector(thisSuperClasses)); // Collect the superclasses and interfaces of this class. Set otherSuperClasses = new HashSet(); otherReferencedClass.hierarchyAccept(false, true, true, false, new ClassCollector(otherSuperClasses)); if (DEBUG) { System.out.println("ReferenceValue.generalize this ["+thisReferencedClass.getName()+"] with other ["+otherReferencedClass.getName()+"]"); System.out.println(" This super classes: "+thisSuperClasses); System.out.println(" Other super classes: "+otherSuperClasses); } // Find the common superclasses. thisSuperClasses.retainAll(otherSuperClasses); if (DEBUG) { System.out.println(" Common super classes: "+thisSuperClasses); } // Find a class that is a subclass of all common superclasses, // or that at least has the maximum number of common superclasses. Clazz commonClazz = null; int maximumSuperClassCount = -1; // Go over all common superclasses to find it. In case of // multiple subclasses, keep the lowest one alphabetically, // in order to ensure that the choice is deterministic. Iterator commonSuperClasses = thisSuperClasses.iterator(); while (commonSuperClasses.hasNext()) { Clazz commonSuperClass = (Clazz)commonSuperClasses.next(); int superClassCount = superClassCount(commonSuperClass, thisSuperClasses); if (maximumSuperClassCount < superClassCount || (maximumSuperClassCount == superClassCount && commonClazz.getName().compareTo(commonSuperClass.getName()) > 0)) { commonClazz = commonSuperClass; maximumSuperClassCount = superClassCount; } } if (commonClazz == null) { throw new IllegalArgumentException("Can't find common super class of ["+thisType+"] and ["+otherType+"]"); } if (DEBUG) { System.out.println(" Best common class: ["+commonClazz.getName()+"]"); } // TODO: Handle more difficult cases, with multiple global subclasses. return new ReferenceValue(commonDimensionCount == 0 ? commonClazz.getName() : ClassUtil.internalArrayTypeFromClassName(commonClazz.getName(), commonDimensionCount), commonClazz, mayBeNull); } } else if (thisDimensionCount > otherDimensionCount) { // See if the other type is an interface type of arrays. if (ClassUtil.isInternalArrayInterfaceName(ClassUtil.internalClassNameFromClassType(otherType))) { return other.generalizeMayBeNull(mayBeNull); } } else if (thisDimensionCount < otherDimensionCount) { // See if this type is an interface type of arrays. if (ClassUtil.isInternalArrayInterfaceName(ClassUtil.internalClassNameFromClassType(thisType))) { return this.generalizeMayBeNull(mayBeNull); } } // Reduce the common dimension count if either type is an array of // primitives type of this dimension. if (commonDimensionCount > 0 && (ClassUtil.isInternalPrimitiveType(otherType.charAt(commonDimensionCount))) || ClassUtil.isInternalPrimitiveType(thisType.charAt(commonDimensionCount))) { commonDimensionCount--; } // Fall back on a basic Object or array of Objects type. return commonDimensionCount == 0 ? mayBeNull ? ValueFactory.REFERENCE_VALUE_JAVA_LANG_OBJECT_MAYBE_NULL : ValueFactory.REFERENCE_VALUE_JAVA_LANG_OBJECT_NOT_NULL : new ReferenceValue(ClassUtil.internalArrayTypeFromClassName(ClassConstants.INTERNAL_NAME_JAVA_LANG_OBJECT, commonDimensionCount), null, mayBeNull); } /** * Returns if the number of superclasses of the given class in the given * set of classes. */ private int superClassCount(Clazz subClass, Set classes) { int count = 0; Iterator iterator = classes.iterator(); while (iterator.hasNext()) { Clazz clazz = (Clazz)iterator.next(); if (subClass.extendsOrImplements(clazz)) { count++; } } //System.out.println("ReferenceValue.superClassCount: ["+subClass.getName()+"]: "+count); return count; } /** * Returns whether this ReferenceValue is equal to the given other * ReferenceValue. * @return <code>NEVER</code>, <code>MAYBE</code>, or <code>ALWAYS</code>. */ public int equal(ReferenceValue other) { return this.type == null && other.type == null ? ALWAYS : MAYBE; } // Derived unary methods. /** * Returns whether this ReferenceValue is not <code>null</code>. * @return <code>NEVER</code>, <code>MAYBE</code>, or <code>ALWAYS</code>. */ public final int isNotNull() { return -isNull(); } /** * Returns the generalization of this ReferenceValue and the given other * ReferenceValue. */ private ReferenceValue generalizeMayBeNull(boolean mayBeNull) { return this.mayBeNull || !mayBeNull ? this : new ReferenceValue(this.type, this.referencedClass, true); } // Derived binary methods. /** * Returns whether this ReferenceValue and the given ReferenceValue are different. * @return <code>NEVER</code>, <code>MAYBE</code>, or <code>ALWAYS</code>. */ public final int notEqual(ReferenceValue other) { return -equal(other); } // Implementations for Value. public final ReferenceValue referenceValue() { return this; } public final Value generalize(Value other) { return this.generalize(other.referenceValue()); } public boolean isSpecific() { return type == null; } public final int computationalType() { return TYPE_REFERENCE; } public final String internalType() { return type == null ? ClassConstants.INTERNAL_TYPE_JAVA_LANG_OBJECT : ClassUtil.isInternalArrayType(type) ? type : ClassConstants.INTERNAL_TYPE_CLASS_START + type + ClassConstants.INTERNAL_TYPE_CLASS_END; } // Implementations for Object. public boolean equals(Object object) { if (object == null || this.getClass() != object.getClass()) { return false; } ReferenceValue other = (ReferenceValue)object; return this.type == null ? other.type == null : (this.mayBeNull == other.mayBeNull && this.type.equals(other.type)); } public int hashCode() { return this.getClass().hashCode() ^ (type == null ? 0 : type.hashCode() ^ (mayBeNull ? 0 : 1)); } public String toString() { return "a:" + (type == null ? "null" : type + (referencedClass == null ? "?" : "") + (mayBeNull ? "" : "!")); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -