import { DiagnosticRule } from '../common/diagnosticRules' ; import { Localizer } from '../localization/localize' ; import { ExpressionNode , ParameterCategory } from '../parser/parseNodes' ; import { getFileInfo } from './analyzerNodeInfo' ; import { Symbol , SymbolFlags } from './symbol' ; import { FunctionArgument , FunctionResult , TypeEvaluator } from './typeEvaluatorTypes' ; import { ClassType , FunctionParameter , FunctionType , FunctionTypeFlags , isClassInstance , isFunction , isInstantiableClass , OverloadedFunctionType , } from './types' ; import { ClassMemberLookupFlags , lookUpObjectMember , synthesizeTypeVarForSelfCls } from './typeUtils' ; export function applyFunctionTransform ( evaluator , errorNode , argList , functionType , result ) { if ( isFunction ( functionType ) ) { if ( functionType . details . fullName === 'functools.total_ordering' ) { return applyTotalOrderingTransform ( evaluator , errorNode , argList , result ) ; } } return result ; } function applyTotalOrderingTransform ( evaluator , errorNode , argList , result ) { if ( argList . length !== 1 ) { return result ; } const classType = argList [ 0 ] . type ; if ( ! classType || ! isInstantiableClass ( classType ) || classType . includeSubclasses ) { return result ; } const orderingMethods = [ '__lt__' , '__le__' , '__gt__' , '__ge__' ] ; const instanceType = ClassType . cloneAsInstance ( classType ) ; const missingMethods = orderingMethods . filter ( ( methodName ) => { return ! lookUpObjectMember ( instanceType , methodName , ClassMemberLookupFlags . SkipInstanceVariables ) ; } ) ; if ( missingMethods . length === orderingMethods . length ) { evaluator . addDiagnostic ( getFileInfo ( errorNode ) . diagnosticRuleSet . reportGeneralTypeIssues , DiagnosticRule . reportGeneralTypeIssues , Localizer . Diagnostic . totalOrderingMissingMethod ( ) , errorNode ) ; return result ; } const objectType = evaluator . getBuiltInObject ( errorNode , 'object' ) ; if ( ! objectType || ! isClassInstance ( objectType ) ) { return result ; } const boolType = evaluator . getBuiltInObject ( errorNode , 'bool' ) ; if ( ! boolType || ! isClassInstance ( boolType ) ) { return result ; } const selfParam = { category : ParameterCategory . Simple , name : 'self' , type : synthesizeTypeVarForSelfCls ( classType , false ) , hasDeclaredType : true , } ; const objParam = { category : ParameterCategory . Simple , name : '__value' , type : objectType , hasDeclaredType : true , } ; missingMethods . forEach ( ( methodName ) => { const methodToAdd = FunctionType . createInstance ( methodName , '' , '' , FunctionTypeFlags . SynthesizedMethod ) ; FunctionType . addParameter ( methodToAdd , selfParam ) ; FunctionType . addParameter ( methodToAdd , objParam ) ; methodToAdd . details . declaredReturnType = boolType ; classType . details . fields . set ( methodName , Symbol . createWithType ( SymbolFlags . ClassMember , methodToAdd ) ) ; } ) ; return result ; }