11package com .semmle .js .parser ;
22
3+ import java .util .ArrayList ;
4+ import java .util .Collections ;
5+ import java .util .LinkedHashMap ;
6+ import java .util .List ;
7+ import java .util .Map ;
8+ import java .util .regex .Matcher ;
9+ import java .util .regex .Pattern ;
10+
311import com .google .gson .JsonArray ;
412import com .google .gson .JsonElement ;
513import com .google .gson .JsonNull ;
3442import com .semmle .js .ast .ExportDeclaration ;
3543import com .semmle .js .ast .ExportDefaultDeclaration ;
3644import com .semmle .js .ast .ExportNamedDeclaration ;
45+ import com .semmle .js .ast .ExportNamespaceSpecifier ;
3746import com .semmle .js .ast .ExportSpecifier ;
3847import com .semmle .js .ast .Expression ;
3948import com .semmle .js .ast .ExpressionStatement ;
144153import com .semmle .ts .ast .UnionTypeExpr ;
145154import com .semmle .util .collections .CollectionUtil ;
146155import com .semmle .util .data .IntList ;
147- import java .util .ArrayList ;
148- import java .util .Collections ;
149- import java .util .LinkedHashMap ;
150- import java .util .List ;
151- import java .util .Map ;
152- import java .util .regex .Matcher ;
153- import java .util .regex .Pattern ;
154156
155157/**
156158 * Utility class for converting a <a
@@ -334,7 +336,11 @@ private Node convertNode(JsonObject node, String defaultKind) throws ParseError
334336 private Node convertNodeUntyped (JsonObject node , String defaultKind ) throws ParseError {
335337 String kind = getKind (node );
336338 if (kind == null ) kind = defaultKind ;
337- if (kind == null ) kind = "Identifier" ;
339+ if (kind == null ) {
340+ // Identifiers and PrivateIdentifiers do not have a "kind" property like other nodes.
341+ // Since we encode identifiers and private identifiers the same, default to Identifier.
342+ kind = "Identifier" ;
343+ }
338344 SourceLocation loc = getSourceLocation (node );
339345 switch (kind ) {
340346 case "AnyKeyword" :
@@ -441,6 +447,7 @@ private Node convertNodeUntyped(JsonObject node, String defaultKind) throws Pars
441447 case "FunctionType" :
442448 return convertFunctionType (node , loc );
443449 case "Identifier" :
450+ case "PrivateIdentifier" :
444451 return convertIdentifier (node , loc );
445452 case "IfStatement" :
446453 return convertIfStatement (node , loc );
@@ -507,6 +514,8 @@ private Node convertNodeUntyped(JsonObject node, String defaultKind) throws Pars
507514 return convertNamespaceDeclaration (node , loc );
508515 case "ModuleBlock" :
509516 return convertModuleBlock (node , loc );
517+ case "NamespaceExport" :
518+ return convertNamespaceExport (node , loc );
510519 case "NamespaceExportDeclaration" :
511520 return convertNamespaceExportDeclaration (node , loc );
512521 case "NamespaceImport" :
@@ -1170,11 +1179,12 @@ private Node convertExportAssignment(JsonObject node, SourceLocation loc) throws
11701179 private Node convertExportDeclaration (JsonObject node , SourceLocation loc ) throws ParseError {
11711180 Literal source = tryConvertChild (node , "moduleSpecifier" , Literal .class );
11721181 if (hasChild (node , "exportClause" )) {
1173- return new ExportNamedDeclaration (
1174- loc ,
1175- null ,
1176- convertChildren (node .get ("exportClause" ).getAsJsonObject (), "elements" ),
1177- source );
1182+ boolean hasTypeKeyword = node .get ("isTypeOnly" ).getAsBoolean ();
1183+ List <ExportSpecifier > specifiers =
1184+ hasKind (node .get ("exportClause" ), "NamespaceExport" )
1185+ ? Collections .singletonList (convertChild (node , "exportClause" ))
1186+ : convertChildren (node .get ("exportClause" ).getAsJsonObject (), "elements" );
1187+ return new ExportNamedDeclaration (loc , null , specifiers , source , hasTypeKeyword );
11781188 } else {
11791189 return new ExportAllDeclaration (loc , source );
11801190 }
@@ -1187,6 +1197,11 @@ private Node convertExportSpecifier(JsonObject node, SourceLocation loc) throws
11871197 convertChild (node , "name" ));
11881198 }
11891199
1200+ private Node convertNamespaceExport (JsonObject node , SourceLocation loc ) throws ParseError {
1201+ // Convert the "* as ns" from an export declaration.
1202+ return new ExportNamespaceSpecifier (loc , convertChild (node , "name" ));
1203+ }
1204+
11901205 private Node convertExpressionStatement (JsonObject node , SourceLocation loc ) throws ParseError {
11911206 Expression expression = convertChild (node , "expression" );
11921207 return new ExpressionStatement (loc , expression );
@@ -1354,6 +1369,7 @@ private Node convertImportClause(JsonObject node, SourceLocation loc) throws Par
13541369 private Node convertImportDeclaration (JsonObject node , SourceLocation loc ) throws ParseError {
13551370 Literal src = tryConvertChild (node , "moduleSpecifier" , Literal .class );
13561371 List <ImportSpecifier > specifiers = new ArrayList <>();
1372+ boolean hasTypeKeyword = false ;
13571373 if (hasChild (node , "importClause" )) {
13581374 JsonObject importClause = node .get ("importClause" ).getAsJsonObject ();
13591375 if (hasChild (importClause , "name" )) {
@@ -1367,8 +1383,9 @@ private Node convertImportDeclaration(JsonObject node, SourceLocation loc) throw
13671383 specifiers .addAll (convertChildren (namedBindings , "elements" ));
13681384 }
13691385 }
1386+ hasTypeKeyword = importClause .get ("isTypeOnly" ).getAsBoolean ();
13701387 }
1371- ImportDeclaration importDecl = new ImportDeclaration (loc , specifiers , src );
1388+ ImportDeclaration importDecl = new ImportDeclaration (loc , specifiers , src , hasTypeKeyword );
13721389 attachSymbolInformation (importDecl , node );
13731390 return importDecl ;
13741391 }
0 commit comments