@@ -258,17 +258,42 @@ const getImportAttributes = (node) => {
258258 return result ;
259259} ;
260260
261+ /** @typedef {typeof VariableInfoFlags.Evaluated | typeof VariableInfoFlags.Free | typeof VariableInfoFlags.Normal | typeof VariableInfoFlags.Tagged } VariableInfoFlagsType */
262+
263+ const VariableInfoFlags = Object . freeze ( {
264+ Evaluated : 0b000 ,
265+ Free : 0b001 ,
266+ Normal : 0b010 ,
267+ Tagged : 0b100
268+ } ) ;
269+
261270class VariableInfo {
262271 /**
263272 * @param {ScopeInfo } declaredScope scope in which the variable is declared
264- * @param {string | true | undefined } freeName which free name the variable aliases, or true when none
273+ * @param {string | undefined } name which name the variable use, defined name or free name or tagged name
274+ * @param {VariableInfoFlagsType } flags how the variable is created
265275 * @param {TagInfo | undefined } tagInfo info about tags
266276 */
267- constructor ( declaredScope , freeName , tagInfo ) {
277+ constructor ( declaredScope , name , flags , tagInfo ) {
268278 this . declaredScope = declaredScope ;
269- this . freeName = freeName ;
279+ this . name = name ;
280+ this . flags = flags ;
270281 this . tagInfo = tagInfo ;
271282 }
283+
284+ /**
285+ * @returns {boolean } the variable is free or not
286+ */
287+ isFree ( ) {
288+ return ( this . flags & VariableInfoFlags . Free ) > 0 ;
289+ }
290+
291+ /**
292+ * @returns {boolean } the variable is tagged by tagVariable or not
293+ */
294+ isTagged ( ) {
295+ return ( this . flags & VariableInfoFlags . Tagged ) > 0 ;
296+ }
272297}
273298
274299/** @typedef {string | ScopeInfo | VariableInfo } ExportedVariableInfo */
@@ -1426,7 +1451,7 @@ class JavascriptParser extends Parser {
14261451 const info = this . getVariableInfo ( /** @type {Identifier } */ ( expr ) . name ) ;
14271452 if (
14281453 typeof info === "string" ||
1429- ( info instanceof VariableInfo && typeof info . freeName === "string" )
1454+ ( info instanceof VariableInfo && ( info . isFree ( ) || info . isTagged ( ) ) )
14301455 ) {
14311456 return {
14321457 name : info ,
@@ -1441,7 +1466,7 @@ class JavascriptParser extends Parser {
14411466 const info = this . getVariableInfo ( "this" ) ;
14421467 if (
14431468 typeof info === "string" ||
1444- ( info instanceof VariableInfo && typeof info . freeName === "string" )
1469+ ( info instanceof VariableInfo && ( info . isFree ( ) || info . isTagged ( ) ) )
14451470 ) {
14461471 return {
14471472 name : info ,
@@ -4053,13 +4078,13 @@ class JavascriptParser extends Parser {
40534078 }
40544079 tagInfo = tagInfo . next ;
40554080 }
4056- if ( info . freeName === true ) {
4081+ if ( ! info . isFree ( ) && ! info . isTagged ( ) ) {
40574082 if ( defined !== undefined ) {
40584083 return defined ( ) ;
40594084 }
40604085 return ;
40614086 }
4062- name = info . freeName ;
4087+ name = info . name ;
40634088 }
40644089 const hook = hookMap . get ( name ) ;
40654090 if ( hook !== undefined ) {
@@ -4818,25 +4843,31 @@ class JavascriptParser extends Parser {
48184843 * @param {string } name name
48194844 * @param {Tag } tag tag info
48204845 * @param {TagData= } data data
4846+ * @param {VariableInfoFlagsType= } flags flags
48214847 */
4822- tagVariable ( name , tag , data ) {
4848+ tagVariable ( name , tag , data , flags = VariableInfoFlags . Tagged ) {
48234849 const oldInfo = this . scope . definitions . get ( name ) ;
48244850 /** @type {VariableInfo } */
48254851 let newInfo ;
48264852 if ( oldInfo === undefined ) {
4827- newInfo = new VariableInfo ( this . scope , name , {
4853+ newInfo = new VariableInfo ( this . scope , name , flags , {
48284854 tag,
48294855 data,
48304856 next : undefined
48314857 } ) ;
48324858 } else if ( oldInfo instanceof VariableInfo ) {
4833- newInfo = new VariableInfo ( oldInfo . declaredScope , oldInfo . freeName , {
4834- tag,
4835- data,
4836- next : oldInfo . tagInfo
4837- } ) ;
4859+ newInfo = new VariableInfo (
4860+ oldInfo . declaredScope ,
4861+ oldInfo . name ,
4862+ /** @type {VariableInfoFlagsType } */ ( oldInfo . flags | flags ) ,
4863+ {
4864+ tag,
4865+ data,
4866+ next : oldInfo . tagInfo
4867+ }
4868+ ) ;
48384869 } else {
4839- newInfo = new VariableInfo ( oldInfo , true , {
4870+ newInfo = new VariableInfo ( oldInfo , name , flags , {
48404871 tag,
48414872 data,
48424873 next : undefined
@@ -4875,7 +4906,7 @@ class JavascriptParser extends Parser {
48754906 const info = this . scope . definitions . get ( name ) ;
48764907 if ( info === undefined ) return false ;
48774908 if ( info instanceof VariableInfo ) {
4878- return info . freeName === true ;
4909+ return ! info . isFree ( ) ;
48794910 }
48804911 return true ;
48814912 }
@@ -4904,7 +4935,12 @@ class JavascriptParser extends Parser {
49044935 } else {
49054936 this . scope . definitions . set (
49064937 name ,
4907- new VariableInfo ( this . scope , variableInfo , undefined )
4938+ new VariableInfo (
4939+ this . scope ,
4940+ variableInfo ,
4941+ VariableInfoFlags . Free ,
4942+ undefined
4943+ )
49084944 ) ;
49094945 }
49104946 } else {
@@ -4917,7 +4953,12 @@ class JavascriptParser extends Parser {
49174953 * @returns {VariableInfo } variable info
49184954 */
49194955 evaluatedVariable ( tagInfo ) {
4920- return new VariableInfo ( this . scope , undefined , tagInfo ) ;
4956+ return new VariableInfo (
4957+ this . scope ,
4958+ undefined ,
4959+ VariableInfoFlags . Evaluated ,
4960+ tagInfo
4961+ ) ;
49214962 }
49224963
49234964 /**
@@ -5002,9 +5043,27 @@ class JavascriptParser extends Parser {
50025043 getFreeInfoFromVariable ( varName ) {
50035044 const info = this . getVariableInfo ( varName ) ;
50045045 let name ;
5005- if ( info instanceof VariableInfo ) {
5006- name = info . freeName ;
5007- if ( typeof name !== "string" ) return ;
5046+ if ( info instanceof VariableInfo && info . name ) {
5047+ if ( ! info . isFree ( ) ) return ;
5048+ name = info . name ;
5049+ } else if ( typeof info !== "string" ) {
5050+ return ;
5051+ } else {
5052+ name = info ;
5053+ }
5054+ return { info, name } ;
5055+ }
5056+
5057+ /**
5058+ * @param {string } varName variable name
5059+ * @returns {{name: string, info: VariableInfo | string} | undefined } name of the free variable and variable info for that
5060+ */
5061+ getNameInfoFromVariable ( varName ) {
5062+ const info = this . getVariableInfo ( varName ) ;
5063+ let name ;
5064+ if ( info instanceof VariableInfo && info . name ) {
5065+ if ( ! info . isFree ( ) && ! info . isTagged ( ) ) return ;
5066+ name = info . name ;
50085067 } else if ( typeof info !== "string" ) {
50095068 return ;
50105069 } else {
@@ -5035,7 +5094,7 @@ class JavascriptParser extends Parser {
50355094 }
50365095 const rootName = getRootName ( callee ) ;
50375096 if ( ! rootName ) return ;
5038- const result = this . getFreeInfoFromVariable ( rootName ) ;
5097+ const result = this . getNameInfoFromVariable ( rootName ) ;
50395098 if ( ! result ) return ;
50405099 const { info : rootInfo , name : resolvedRoot } = result ;
50415100 const calleeName = objectAndMembersToName ( resolvedRoot , rootMembers ) ;
@@ -5058,7 +5117,7 @@ class JavascriptParser extends Parser {
50585117 const rootName = getRootName ( object ) ;
50595118 if ( ! rootName ) return ;
50605119
5061- const result = this . getFreeInfoFromVariable ( rootName ) ;
5120+ const result = this . getNameInfoFromVariable ( rootName ) ;
50625121 if ( ! result ) return ;
50635122 const { info : rootInfo , name : resolvedRoot } = result ;
50645123 return {
@@ -5151,4 +5210,5 @@ module.exports.ALLOWED_MEMBER_TYPES_CALL_EXPRESSION =
51515210module . exports . ALLOWED_MEMBER_TYPES_EXPRESSION =
51525211 ALLOWED_MEMBER_TYPES_EXPRESSION ;
51535212module . exports . VariableInfo = VariableInfo ;
5213+ module . exports . VariableInfoFlags = VariableInfoFlags ;
51545214module . exports . getImportAttributes = getImportAttributes ;
0 commit comments