import { guessType } from "." ; import { Argument , Decorator , DocstringParts , Exception , KeywordArgument , Returns , Yields , } from "../docstring_parts" ; export function parseParameters ( parameterTokens , body , functionName ) { return { name : functionName , decorators : parseDecorators ( parameterTokens ) , args : parseArguments ( parameterTokens ) , kwargs : parseKeywordArguments ( parameterTokens ) , returns : parseReturn ( parameterTokens , body ) , yields : parseYields ( parameterTokens , body ) , exceptions : parseExceptions ( body ) , } ; } function parseDecorators ( parameters ) { const decorators = [ ] ; const pattern = /^@(\w+)/ ; for ( const param of parameters ) { const match = param . trim ( ) . match ( pattern ) ; if ( match == null ) { continue ; } decorators . push ( { name : match [ 1 ] , } ) ; } return decorators ; } function parseArguments ( parameters ) { const args = [ ] ; const excludedArgs = [ "self" , "cls" ] ; const pattern = /^(\w+)/ ; for ( const param of parameters ) { const match = param . trim ( ) . match ( pattern ) ; if ( match == null || param . includes ( "=" ) || inArray ( param , excludedArgs ) ) { continue ; } args . push ( { var : match [ 1 ] , type : guessType ( param ) , } ) ; } return args ; } function parseKeywordArguments ( parameters ) { const kwargs = [ ] ; const pattern = /^(\w+)(?:\s*:[^=]+)?\s*=\s*(.+)/ ; for ( const param of parameters ) { const match = param . trim ( ) . match ( pattern ) ; if ( match == null ) { continue ; } kwargs . push ( { var : match [ 1 ] , default : match [ 2 ] , type : guessType ( param ) , } ) ; } return kwargs ; } function parseReturn ( parameters , body ) { const returnType = parseReturnFromDefinition ( parameters ) ; if ( returnType == null || isIterator ( returnType . type ) ) { return parseFromBody ( body , /return / ) ; } return returnType ; } function parseYields ( parameters , body ) { const returnType = parseReturnFromDefinition ( parameters ) ; if ( returnType != null && isIterator ( returnType . type ) ) { return returnType as Yields ; } const yieldType = returnType ? returnType . type : undefined ; const yieldInBody = parseFromBody ( body , /yield / ) ; if ( yieldInBody != null && yieldType != undefined ) { yieldInBody . type = `Iterator[${ yieldType }]` ; } return yieldInBody ; } function parseReturnFromDefinition ( parameters ) { const pattern = /^->\s*(["']?)([\w\[\], \.]*)\1/ ; for ( const param of parameters ) { const match = param . trim ( ) . match ( pattern ) ; if ( match == null ) { continue ; } return match [ 2 ] === "None" ? null : { type : match [ 2 ] } ; } return null ; } function parseExceptions ( body ) { const exceptions = [ ] ; const pattern = /(?<!#.*)raise\s+([\w.]+)/ ; for ( const line of body ) { const match = line . match ( pattern ) ; if ( match == null ) { continue ; } exceptions . push ( { type : match [ 1 ] } ) ; } return exceptions ; } export function inArray < type > ( item , array ) { return array . some ( ( x ) => item === x ) ; } function parseFromBody ( body , pattern ) { for ( const line of body ) { const match = line . match ( pattern ) ; if ( match == null ) { continue ; } return { type : undefined } ; } return undefined ; } param type function isIterator ( type ) { return type . startsWith ( "Generator" ) || type . startsWith ( "Iterator" ) ; }