MethodOrValue mov = CodegenUtil.findMethodOrValueForParam(param);
int mods = 0;
if (!Decl.isNonTransientValue(mov) || !mov.isVariable() || mov.isCaptured()) {
mods |= FINAL;
}
TypedDeclaration nonWideningDecl = null;
ProducedType nonWideningType;
if (Decl.isValue(mov)) {
ProducedTypedReference typedRef = gen.getTypedReference(mov);
ProducedTypedReference nonWideningTypedRef = gen.nonWideningTypeDecl(typedRef);
nonWideningType = gen.nonWideningType(typedRef, nonWideningTypedRef);
nonWideningDecl = nonWideningTypedRef.getDeclaration();
}else{
nonWideningType = param.getType();
nonWideningDecl = param.getModel();
}
// make sure we don't accidentally narrow parameters that would be erased in the topmost declaration
if(canWiden){
TypedDeclaration refinedParameter = (TypedDeclaration)CodegenUtil.getTopmostRefinedDeclaration(param.getModel());
if(!Decl.equal(refinedParameter, param.getDeclaration())){
ProducedType refinedParameterType;
// we don't have to use produced typed references with type params applied here because we want to know the
// erasure status of the compilation of the refined parameter, so it's OK if we end up with unbound type parameters
// in the refined parameter type
if(refinedParameter instanceof Method)
refinedParameterType = refinedParameter.getProducedTypedReference(null, Collections.<ProducedType>emptyList()).getFullType();
else
refinedParameterType = refinedParameter.getType();
// if the supertype method itself got erased to Object, we can't do better than this
if(gen.willEraseToObject(refinedParameterType) && !gen.willEraseToBestBounds(param))
nonWideningType = gen.typeFact().getObjectDeclaration().getType();
}
}