import { CodeType } from "../Domain/IDocommentDomain" ; import { CommentSyntax } from "../Entity/Config/Contributes/Configuration" ; export class SyntacticAnalysisCSharp { private static RESERVED_WORDS : RegExp = /(void|event|delegate|internal|public|protected|private|static|const|new|sealed|abstract|virtual|override|extern|unsafe|readonly|volatile|implicit|explicit|operator)/ ; public static IsEnterKey ( eventText ) { return ( eventText . startsWith ( '\n' ) || eventText . startsWith ( "\r\n" ) ) ; } public static IsAfterDocomment ( eventText ) { return eventText . match ( /^\n[ \t]+[\S]+/ ) !== null || eventText . match ( /^\r\n[ \t]+[\S]+/ ) !== null ; } public static IsInsertLineAbove ( activeLine ) { return activeLine !== null && activeLine . trim ( ) . length === 0 ; } public static IsActivationKey ( activeChar , syntax ) { switch ( syntax ) { case CommentSyntax . single : return activeChar === '/' ; case CommentSyntax . delimited : return activeChar === '*' ; } } param activeLine public static IsDocCommentStrict ( activeLine , syntax ) { switch ( syntax ) { case CommentSyntax . single : return activeLine . match ( /^[ \t]*\/{3}[ \t]*$/ ) !== null ; case CommentSyntax . delimited : return activeLine . match ( /^[ \t]*\/\*{2}[ \t]*$/ ) !== null ; } } public static IsDocComment ( activeLine , syntax ) { switch ( syntax ) { case CommentSyntax . single : return activeLine . match ( /\/{3}/ ) !== null ; case CommentSyntax . delimited : return ( ( activeLine . match ( /^[ \t]*\*{1}[^\/]/ ) !== null ) || this . IsDocCommentStrict ( activeLine , syntax ) ) ; } } public static IsDocCommentOnActivationEnter ( activeLine , syntax ) { switch ( syntax ) { case CommentSyntax . single : return activeLine . match ( /^[ \t]*\/{3}$/ ) !== null ; case CommentSyntax . delimited : return activeLine . match ( /^[ \t]*\/\*{2}[ \t]*$/ ) !== null || SyntacticAnalysisCSharp . IsDocComment ( activeLine , syntax ) ; } } public static IsDoubleDocComment ( activeLine , syntax ) { switch ( syntax ) { case CommentSyntax . single : return activeLine . match ( /^[ \t]*\/{3} $/ ) !== null ; case CommentSyntax . delimited : return activeLine . match ( /^[ \t]*\*{1} $/ ) !== null ; } } public static IsAttribute ( code ) { if ( code === null ) return false ; return code . match ( /^\[.+\]$/ ) !== null ; } public static IsNamespace ( code ) { if ( code === null ) return false ; return code . match ( /\bnamespace\b/ ) !== null ; } public static IsClass ( code ) { if ( code === null ) return false ; return code . match ( /\bclass\b/ ) !== null ; } public static IsInterface ( code ) { if ( code === null ) return false ; return code . match ( /\binterface\b/ ) !== null ; } public static IsStruct ( code ) { if ( code === null ) return false ; return code . match ( /\bstruct\b/ ) !== null ; } public static IsEnum ( code ) { if ( code === null ) return false ; return code . match ( /\benum\b/ ) !== null ; } public static IsDelegate ( code ) { if ( code === null ) return false ; return code . match ( /\bdelegate\b/ ) !== null ; } public static IsEvent ( code ) { if ( code === null ) return false ; return code . match ( /\bevent\b/ ) !== null ; } public static IsProperty ( code ) { if ( code === null ) return false ; return code . match ( /[\w\S]+[^)]?(\b)?\s*{/ ) !== null ; } public static IsField ( code ) { if ( code === null ) return false ; return code . match ( /[^()]+;[ \t]*$/ ) !== null ; } public static IsMethod ( code ) { if ( code === null ) return false ; return code . match ( /[\w\S]\s+[\w\S]+\s*\(.*\)/ ) !== null ; } public static IsComment ( code ) { if ( code === null ) return false ; return true ; } public static GetCommentSyntax ( syntax ) { switch ( syntax ) { case CommentSyntax . single : return '///' ; case CommentSyntax . delimited : return '*' ; } } public static GetGenericList ( code ) { if ( code === null ) return null ; const isAfterExtends = code . match ( /:.+<([^<>]*)>/ ) !== null ; if ( isAfterExtends ) { const isBeforeExtends = code . match ( /<([^<>]*)>.+:/ ) !== null ; if ( ! isBeforeExtends ) return null ; } const generics = code . match ( /<([^<>]*)>/ ) ; const isUnMatched = ( generics === null || generics . length !== 2 ) ; if ( isUnMatched ) return null ; let genericNames = new Array < string > ( ) ; generics [ 1 ] . split ( ',' ) . forEach ( param => { const name = param . match ( /(\S+)\s*$/ ) ; if ( name !== null && name . length === 2 ) { genericNames . push ( name [ 1 ] ) ; } } ) ; return genericNames ; } public static GetGenericMethodsList ( code ) { if ( code === null ) return null ; const generics = code . match ( /<([^<>]*)>\s*\(/ ) ; const isUnMatched = ( generics === null || generics . length !== 2 ) ; if ( isUnMatched ) return null ; let genericNames = new Array < string > ( ) ; generics [ 1 ] . split ( ',' ) . forEach ( param => { const name = param . match ( /(\S+)\s*$/ ) ; if ( name !== null && name . length === 2 ) { genericNames . push ( name [ 1 ] ) ; } } ) ; return genericNames ; } public static GetMethodParamNameList ( code ) { if ( code === null ) return null ; const removedAttrCode = code . replace ( /^\s*\[.+?\]/ , '' ) ; const removedExtendsCode = removedAttrCode . replace ( /:.+/ , '' ) ; const removedLamdaCode = removedExtendsCode . replace ( /=>.*/ , '' ) ; const removedArrayCode = removedLamdaCode . replace ( /\[.*?\]/g , '' ) ; const params = removedArrayCode . match ( /\((.+)\)/s ) ; const isMatched = ( params === null || params . length !== 2 ) ; if ( isMatched ) return null ; let paramNames = new Array < string > ( ) ; params [ 1 ] . split ( ',' ) . forEach ( param => { const hasOpen = param . match ( /</ ) !== null ; const hasClose = param . match ( />/ ) !== null ; const isHighOrderParam = hasOpen && ! hasClose ; if ( isHighOrderParam ) { return ; } const hasOptionalParam = param . match ( /\S+\s+\S+\s*=/ ) !== null ; const hasTypeInfo = param . match ( /[\w\W]+\s+[\w\W]+/ ) !== null ; let name = null ; if ( hasOptionalParam ) { name = param . match ( /\S+\s+(\S+)\s*=.*/ ) ; } else if ( ! hasTypeInfo ) { name = null ; } else { name = param . match ( /(\S+)\s*$/ ) ; } if ( name !== null && name . length === 2 ) { const hasIdentifer = name [ 1 ] . startsWith ( '@' ) ; const paramName = ( hasIdentifer ) ? name [ 1 ] . replace ( '@' , '' ) : name [ 1 ] ; paramNames . push ( paramName ) ; } } ) ; return paramNames ; } public static HasMethodReturn ( code ) { if ( code === null ) { return false ; } { const returns = code . match ( /([\w\S]+)\s+[\w\S]+\s*\(.*\)/ ) ; const isMatched = ( returns !== null && returns . length === 2 ) ; if ( isMatched ) { const isReserved = ( returns [ 1 ] . match ( this . RESERVED_WORDS ) !== null ) ; if ( ! isReserved ) { return true ; } } } { const returns = code . match ( /([\w\S]+)\s+[\w\S]+\s+[\w\S]+\s*\(.*\)/ ) ; const isMatched = ( returns !== null && returns . length === 2 ) ; if ( isMatched ) { const isReserved = ( returns [ 1 ] . match ( this . RESERVED_WORDS ) !== null ) ; if ( ! isReserved ) { return true ; } } } return false ; } public static HasPropertyReturn ( code ) { if ( code === null ) return false ; const returns = code . match ( /([\w\S]+)\s+[\w\S]+\s*\{/ ) ; const isMatched = ( returns === null || returns . length !== 2 ) ; if ( isMatched ) return false ; return ( returns [ 1 ] . match ( this . RESERVED_WORDS ) === null ) ? true : false ; } public static GetLineOffset ( syntax , codeType ) { switch ( syntax ) { case CommentSyntax . single : return 1 ; case CommentSyntax . delimited : switch ( codeType ) { case CodeType . Comment : return 1 ; default : return 2 ; } } } }