@@ -15,7 +15,7 @@ export class ParserService {
1515 // Keywords that should never be treated as variables
1616 private static EXCLUDE : Record < string , Set < string > > = {
1717 javascript : new Set ( [ 'if' , 'else' , 'for' , 'while' , 'switch' , 'catch' , 'function' , 'const' , 'let' , 'var' , 'class' , 'return' , 'console' , 'require' , 'import' , 'export' , 'new' , 'this' , 'typeof' , 'instanceof' , 'true' , 'false' , 'null' , 'undefined' , 'void' ] ) ,
18- typescript : new Set ( [ 'if' , 'else' , 'for' , 'while' , 'switch' , 'catch' , 'function' , 'const' , 'let' , 'var' , 'class' , 'return' , 'console' , 'require' , 'import' , 'export' , 'new' , 'this' , 'typeof' , 'instanceof' , 'true' , 'false' , 'null' , 'undefined' , 'void' , 'interface' , 'type' , 'enum' , 'namespace' , 'abstract' , 'implements' , 'extends' , 'readonly' , 'public' , 'private' , 'protected' , 'static' , 'async' , 'await' , 'number' , 'string' , 'boolean' , 'any' , 'never' , 'unknown' , 'infer' , 'keyof' , 'typeof ' , 'declare ' ] ) ,
18+ typescript : new Set ( [ 'if' , 'else' , 'for' , 'while' , 'switch' , 'catch' , 'function' , 'const' , 'let' , 'var' , 'class' , 'return' , 'console' , 'require' , 'import' , 'export' , 'new' , 'this' , 'typeof' , 'instanceof' , 'true' , 'false' , 'null' , 'undefined' , 'void' , 'interface' , 'type' , 'enum' , 'namespace' , 'abstract' , 'implements' , 'extends' , 'readonly' , 'public' , 'private' , 'protected' , 'static' , 'async' , 'await' , 'number' , 'string' , 'boolean' , 'any' , 'never' , 'unknown' , 'infer' , 'keyof' , 'declare ' , 'get' , 'set' , 'constructor' , 'super' , 'break' , 'continue' , 'do' , 'try' , 'finally' , 'throw' , 'case' , 'default' , 'yield' , 'delete' , 'with' , 'debugger' , 'as' , 'from' , 'of' , 'in '] ) ,
1919 python : new Set ( [ 'if' , 'else' , 'elif' , 'for' , 'while' , 'class' , 'return' , 'print' , 'range' , 'def' , 'import' , 'from' , 'with' , 'as' , 'try' , 'except' , 'pass' , 'and' , 'or' , 'not' , 'in' , 'is' , 'True' , 'False' , 'None' , 'lambda' , 'yield' , 'global' , 'nonlocal' , 'assert' , 'break' , 'continue' , 'del' , 'raise' ] ) ,
2020 java : new Set ( [ 'if' , 'else' , 'for' , 'while' , 'switch' , 'catch' , 'new' , 'return' , 'class' , 'throw' , 'System' , 'public' , 'private' , 'static' , 'void' , 'int' , 'long' , 'double' , 'boolean' , 'String' , 'true' , 'false' , 'null' ] ) ,
2121 c : new Set ( [ 'if' , 'else' , 'for' , 'while' , 'switch' , 'return' , 'printf' , 'scanf' , 'include' , 'define' , 'int' , 'float' , 'char' , 'void' , 'unsigned' , 'long' , 'short' , 'struct' , 'typedef' , 'NULL' ] ) ,
@@ -106,6 +106,32 @@ export class ParserService {
106106 }
107107
108108 } else if ( lang === 'javascript' || lang === 'typescript' ) {
109+ // Class/Interface method: public methodName(...) or methodName(...)
110+ const methodMatch = trimmed . match ( / ^ (?: (?: p u b l i c | p r i v a t e | p r o t e c t e d | s t a t i c | a s y n c | r e a d o n l y ) \s + ) * ( [ a - z A - Z _ ] [ a - z A - Z 0 - 9 _ ] * ) \s * \( ( [ ^ ) ] * ) \) / ) ;
111+ if ( methodMatch && ! trimmed . startsWith ( 'function ' ) && ! trimmed . startsWith ( 'if' ) && ! trimmed . startsWith ( 'for' ) && ! trimmed . startsWith ( 'while' ) && ! trimmed . startsWith ( 'switch' ) ) {
112+ const methodName = methodMatch [ 1 ] ;
113+ // Only add method name if it's not a keyword
114+ if ( ! excludeSet . has ( methodName ) ) {
115+ addDef ( methodName , lineNum , line ) ;
116+ }
117+ // Parse parameters
118+ const parenIdx = line . indexOf ( '(' , line . indexOf ( methodName ) ) ;
119+ const paramsStr = methodMatch [ 2 ] || '' ;
120+ let searchFrom = parenIdx + 1 ;
121+ if ( paramsStr . trim ( ) ) {
122+ paramsStr . split ( ',' ) . forEach ( rawP => {
123+ const p = rawP . trim ( ) . split ( '=' ) [ 0 ] . trim ( ) . split ( ':' ) [ 0 ] . trim ( ) . replace ( / ^ \. \. \. / , '' ) . replace ( / [ ? ] / g, '' ) ;
124+ if ( p && ! excludeSet . has ( p ) ) {
125+ const col = line . indexOf ( p , searchFrom ) ;
126+ if ( col !== - 1 ) {
127+ definitions . set ( p , { name : p , line : lineNum , startCol : col , endCol : col + p . length } ) ;
128+ searchFrom = col + p . length ;
129+ }
130+ }
131+ } ) ;
132+ }
133+ }
134+
109135 // Function declaration: function foo(a, b) or const foo = (a, b) => or const foo = async (a, b) =>
110136 const fnDeclMatch = trimmed . match ( / (?: f u n c t i o n \s + ( [ a - z A - Z _ ] [ a - z A - Z 0 - 9 _ ] * ) \s * | (?: c o n s t | l e t | v a r ) \s + ( [ a - z A - Z _ ] [ a - z A - Z 0 - 9 _ ] * ) \s * = \s * (?: a s y n c \s * ) ? (?: f u n c t i o n \s * ) ? \( ) \s * ( [ ^ ) ] * ) \) / ) ;
111137 if ( fnDeclMatch ) {
@@ -114,16 +140,18 @@ export class ParserService {
114140 const parenIdx = line . indexOf ( '(' ) ;
115141 const paramsStr = fnDeclMatch [ 3 ] || '' ;
116142 let searchFrom = parenIdx + 1 ;
117- paramsStr . split ( ',' ) . forEach ( rawP => {
118- const p = rawP . trim ( ) . split ( '=' ) [ 0 ] . trim ( ) . split ( ':' ) [ 0 ] . trim ( ) . replace ( / ^ \. \. \. / , '' ) ;
119- if ( p ) {
120- const col = line . indexOf ( p , searchFrom ) ;
121- if ( col !== - 1 && ! excludeSet . has ( p ) ) {
122- definitions . set ( p , { name : p , line : lineNum , startCol : col , endCol : col + p . length } ) ;
123- searchFrom = col + p . length ;
143+ if ( paramsStr . trim ( ) ) {
144+ paramsStr . split ( ',' ) . forEach ( rawP => {
145+ const p = rawP . trim ( ) . split ( '=' ) [ 0 ] . trim ( ) . split ( ':' ) [ 0 ] . trim ( ) . replace ( / ^ \. \. \. / , '' ) . replace ( / [ ? ] / g, '' ) ;
146+ if ( p && ! excludeSet . has ( p ) ) {
147+ const col = line . indexOf ( p , searchFrom ) ;
148+ if ( col !== - 1 ) {
149+ definitions . set ( p , { name : p , line : lineNum , startCol : col , endCol : col + p . length } ) ;
150+ searchFrom = col + p . length ;
151+ }
124152 }
125- }
126- } ) ;
153+ } ) ;
154+ }
127155 }
128156
129157 // TS: interface/type/enum/class declaration
@@ -134,6 +162,10 @@ export class ParserService {
134162 const varMatch = trimmed . match ( / ^ (?: c o n s t | l e t | v a r ) \s + ( [ a - z A - Z _ ] [ a - z A - Z 0 - 9 _ ] * ) / ) ;
135163 if ( varMatch ) addDef ( varMatch [ 1 ] , lineNum , line ) ;
136164
165+ // Class properties: private _view?: Type or public name: string
166+ const propMatch = trimmed . match ( / ^ (?: p u b l i c | p r i v a t e | p r o t e c t e d | r e a d o n l y | s t a t i c ) \s + ( [ a - z A - Z _ ] [ a - z A - Z 0 - 9 _ ] * ) [ ? : ] ? \s * : / ) ;
167+ if ( propMatch ) addDef ( propMatch [ 1 ] , lineNum , line ) ;
168+
137169 // For loop: for (let i = 0...) or for (const x of arr)
138170 const forMatch = trimmed . match ( / ^ f o r \s * \( \s * (?: l e t | c o n s t | v a r ) ? \s * ( [ a - z A - Z _ ] [ a - z A - Z 0 - 9 _ ] * ) / ) ;
139171 if ( forMatch ) addDef ( forMatch [ 1 ] , lineNum , line ) ;
0 commit comments