@Override protected boolean isRawTypeInheritance() { if (getDeclaration().isStatic()) { return false; } return super.isRawTypeInheritance(); }
@Override public LightweightTypeReference getResolvedReturnType() { if (returnType != null) return returnType; return returnType = getResolvedReference(getDeclaration().getReturnType()); }
@Override public IResolvedOperation getOverriddenMethod() { if (!getDeclaration().isAbstract() && getDeclaration().getVisibility() != JvmVisibility.PRIVATE) { List<IResolvedOperation> overriddenAndImplemented = getOverriddenAndImplementedMethods(); for(IResolvedOperation candidate: overriddenAndImplemented) { if (!candidate.getDeclaration().isAbstract()) { return candidate; } } } return null; }
@Override public List<LightweightTypeReference> getIllegallyDeclaredExceptions() { if (getDeclaration().getExceptions().isEmpty()) return Collections.emptyList(); List<IResolvedOperation> overriddenAndImplemented = getOverriddenAndImplementedMethods(); if (overriddenAndImplemented.isEmpty()) return Collections.emptyList(); List<LightweightTypeReference> exceptions = getResolvedExceptions(); List<LightweightTypeReference> result = Lists.newArrayListWithCapacity(exceptions.size()); for(LightweightTypeReference exception: exceptions) { if (!exception.isSubtypeOf(RuntimeException.class) && !exception.isSubtypeOf(Error.class)) { if (isIllegallyDeclaredException(exception, overriddenAndImplemented)) { result.add(exception); } } } return result; }
protected List<IResolvedOperation> computeAllOperations() { JvmType rawType = getRawType(); if (!(rawType instanceof JvmDeclaredType)) { return Collections.emptyList(); } Multimap<String, AbstractResolvedOperation> processedOperations = LinkedHashMultimap.create(); for (IResolvedOperation resolvedOperation : getDeclaredOperations()) { processedOperations.put(resolvedOperation.getDeclaration().getSimpleName(), (AbstractResolvedOperation) resolvedOperation); } if (targetVersion.isAtLeast(JavaVersion.JAVA8)) { computeAllOperationsFromSortedSuperTypes((JvmDeclaredType) rawType, processedOperations); } else { Set<JvmType> processedTypes = Sets.newHashSet(rawType); computeAllOperationsFromSuperTypes((JvmDeclaredType) rawType, processedOperations, processedTypes); } // make sure the declared operations are the first in the list List<IResolvedOperation> result = new ArrayList<IResolvedOperation>(processedOperations.size()); result.addAll(getDeclaredOperations()); for (AbstractResolvedOperation operation : processedOperations.values()) { if (operation.getDeclaration().getDeclaringType() != rawType) { result.add(operation); } } return Collections.unmodifiableList(result); }
protected void addAdditionalDetails(AbstractResolvedOperation overriding, AbstractResolvedOperation overridden, EnumSet<OverrideCheckDetails> result) { addReturnTypeDetails(overriding, overridden, result); addExceptionDetails(overriding, overridden, result); JvmOperation overridingDecl = overriding.getDeclaration(); JvmOperation overriddenDecl = overridden.getDeclaration(); if (isMorePrivateThan(overridingDecl.getVisibility(), overriddenDecl.getVisibility())) { result.add(OverrideCheckDetails.REDUCED_VISIBILITY); } if (overriddenDecl.isFinal()) { result.add(OverrideCheckDetails.IS_FINAL); } if (overridingDecl.isVarArgs() != overriddenDecl.isVarArgs()) { result.add(OverrideCheckDetails.VAR_ARG_MISMATCH); } if (isConflictingDefaultImplementation(overriding, overridden)) { result.add(OverrideCheckDetails.DEFAULT_IMPL_CONFLICT); } if (!overridingDecl.isSynchronized() && overriddenDecl.isSynchronized()) { result.add(OverrideCheckDetails.SYNCHRONIZED_MISMATCH); } }
protected boolean isConflictingDefaultImplementation(AbstractResolvedOperation overriding, AbstractResolvedOperation overridden) { JvmOperation ridingDecl = overriding.getDeclaration(); JvmOperation riddenDecl = overridden.getDeclaration(); if (isInterface(ridingDecl.getDeclaringType()) && isInterface(riddenDecl.getDeclaringType()) && (!ridingDecl.isAbstract() || !riddenDecl.isAbstract())) { LightweightTypeReference ridingTypeRef = overriding.getResolvedDeclarator(); LightweightTypeReference riddenTypeRef = overridden.getResolvedDeclarator(); return !riddenTypeRef.isAssignableFrom(ridingTypeRef); } return false; }
@Override public List<JvmOperation> getOverriddenAndImplementedMethodCandidates() { if (overrideCandidates != null) return overrideCandidates; // here we are only interested in the raw type thus the declarator is not substituted // the found operation will be put in the right context by clients, e.g. #getOverriddenAndImplementedMethods ParameterizedTypeReference currentDeclarator = getContextType().getOwner().newParameterizedTypeReference(getDeclaration().getDeclaringType()); List<LightweightTypeReference> superTypes = currentDeclarator.getSuperTypes(); List<JvmOperation> result = Lists.newArrayListWithCapacity(5); for(LightweightTypeReference superType: superTypes) { if (superType.getType() instanceof JvmDeclaredType) { JvmDeclaredType declaredSuperType = (JvmDeclaredType) superType.getType(); if (declaredSuperType != null) { Iterable<JvmFeature> equallyNamedFeatures = declaredSuperType.findAllFeaturesByName(getDeclaration().getSimpleName()); for(JvmFeature equallyNamedFeature: equallyNamedFeatures) { if (equallyNamedFeature instanceof JvmOperation) { result.add((JvmOperation) equallyNamedFeature); } } } } } return overrideCandidates = Collections.unmodifiableList(result); }
ConflictingDefaultOperation resolvedOperation = createConflictingOperation(conflictingOperations.get(0).getDeclaration()); resolvedOperation.getConflictingOperations().add(createResolvedOperation(operation)); for (AbstractResolvedOperation conflictingOp : conflictingOperations) { processedOperations.remove(simpleName, conflictingOp); if (conflictingOp.getDeclaration() != resolvedOperation.getDeclaration()) { resolvedOperation.getConflictingOperations().add(conflictingOp);
ConflictingDefaultOperation resolvedOperation = createConflictingOperation(conflictingOperations.get(0).getDeclaration()); resolvedOperation.getConflictingOperations().add(createResolvedOperation(operation)); for (AbstractResolvedOperation conflictingOp : conflictingOperations) { processedOperations.remove(simpleName, conflictingOp); if (conflictingOp.getDeclaration() != resolvedOperation.getDeclaration()) { resolvedOperation.getConflictingOperations().add(conflictingOp);
protected void addReturnTypeDetails(AbstractResolvedOperation overriding, AbstractResolvedOperation overridden, EnumSet<OverrideCheckDetails> result) { LightweightTypeReference overridingReturnType = overriding.getResolvedReturnType(); LightweightTypeReference overriddenReturnType = overridden.getResolvedReturnType(); TypeConformanceComputationArgument conformanceArgument = new TypeConformanceComputationArgument(false, false, false, false, false, false); if (!overriddenReturnType.isAssignableFrom(overridingReturnType, conformanceArgument)) { if (overriding.getTypeParameters().isEmpty() && !overridden.getTypeParameters().isEmpty()) { TypeConformanceComputationArgument rawConformanceArgument = new TypeConformanceComputationArgument(true, false, false, false, false, false); if (!overriddenReturnType.isAssignableFrom(overridingReturnType, rawConformanceArgument)) { result.add(OverrideCheckDetails.RETURN_MISMATCH); } else { result.add(OverrideCheckDetails.UNCHECKED_CONVERSION_REQUIRED); if (overridingReturnType.getRawTypeReference().getType() != overriddenReturnType.getRawTypeReference().getType()) { result.add(OverrideCheckDetails.COVARIANT_RETURN); } } } else { result.add(OverrideCheckDetails.RETURN_MISMATCH); } } else if (!overriddenReturnType.getJavaIdentifier().equals(overridingReturnType.getJavaIdentifier())) { if (!overridden.isRawTypeInheritance() && overriding.getTypeParameters().isEmpty() && !overridden.getTypeParameters().isEmpty()) { if (overridden.getTypeParameters().contains(overridden.getDeclaration().getReturnType().getType())) { result.add(OverrideCheckDetails.UNCHECKED_CONVERSION_REQUIRED); } } result.add(OverrideCheckDetails.COVARIANT_RETURN); } }
JvmOperation declaration = overriding.getDeclaration(); if (declaration == overridden) { return new LazyOverrideCheckResult(overriding, overridden, OverrideCheckDetails.CURRENT);