Skip to content

Commit c8817d9

Browse files
committed
JS: Parse with proper locations
1 parent cc2bec0 commit c8817d9

File tree

3 files changed

+144
-141
lines changed

3 files changed

+144
-141
lines changed

javascript/extractor/src/com/semmle/js/parser/JSDocParser.java

Lines changed: 13 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ private static boolean isIdentifierPart(char ch) {
114114
}
115115

116116
private static boolean isTypeName(char ch) {
117-
return "><(){}[],:*|?!=".indexOf(ch) == -1 && !isWhiteSpace(ch) && !isLineTerminator(ch);
117+
return "><(){}[],:*|?!=.".indexOf(ch) == -1 && !isWhiteSpace(ch) && !isLineTerminator(ch);
118118
}
119119

120120
private static boolean isParamTitle(String title) {
@@ -536,20 +536,9 @@ private Token scanNumber() throws ParseError {
536536
}
537537

538538
private Token scanTypeName() {
539-
char ch, ch2;
540-
541539
StringBuilder sb = new StringBuilder();
542540
sb.append((char)advance());
543541
while (index < endIndex && isTypeName(source.charAt(index))) {
544-
ch = source.charAt(index);
545-
if (ch == '.') {
546-
if ((index + 1) < endIndex) {
547-
ch2 = source.charAt(index + 1);
548-
if (ch2 == '<') {
549-
break;
550-
}
551-
}
552-
}
553542
sb.append((char)advance());
554543
}
555544
value = sb.toString();
@@ -827,15 +816,21 @@ private JSDocTypeExpression parseRecordType() throws ParseError {
827816
return finishNode(new RecordType(loc, fields));
828817
}
829818

830-
private JSDocTypeExpression parseNameExpression() throws ParseError {
819+
private Identifier parseIdentifier() throws ParseError {
831820
SourceLocation loc = loc();
832821
Object value = this.value; // save the value of the current token
833822
expect(Token.NAME);
834-
// Hacky initial implementation with wrong locations
835-
String[] parts = value.toString().split("\\.");
836-
JSDocTypeExpression node = finishNode(new Identifier(loc, parts[0]));
837-
for (int i = 1; i < parts.length; i++) {
838-
Identifier memberName = finishNode(new Identifier(loc, parts[i]));
823+
return finishNode(new Identifier(loc, value.toString()));
824+
}
825+
826+
private JSDocTypeExpression parseNameExpression() throws ParseError {
827+
JSDocTypeExpression node = parseIdentifier();
828+
while (token == Token.DOT) {
829+
consume(Token.DOT);
830+
Identifier memberName = parseIdentifier();
831+
// Create a SourceLocation object with the correct start location.
832+
// The call to finishNode() will set the end location.
833+
SourceLocation loc = new SourceLocation(node.getLoc());
839834
node = finishNode(new QualifiedNameExpression(loc, node, memberName));
840835
}
841836
return node;

javascript/extractor/tests/comments/output/trap/jsdoc.js.trap

Lines changed: 126 additions & 118 deletions
Original file line numberDiff line numberDiff line change
@@ -523,156 +523,164 @@ locations_default(#20160,#10000,11,26,11,37)
523523
hasLocation(#20159,#20160)
524524
#20161=*
525525
jsdoc_type_exprs(#20161,15,#20159,0,"goog.ui")
526-
hasLocation(#20161,#20160)
527-
#20162=*
528-
jsdoc_type_exprs(#20162,5,#20161,0,"goog")
529-
hasLocation(#20162,#20160)
526+
#20162=@"loc,{#10000},11,26,11,32"
527+
locations_default(#20162,#10000,11,26,11,32)
528+
hasLocation(#20161,#20162)
530529
#20163=*
531-
jsdoc_type_exprs(#20163,5,#20161,1,"ui")
532-
hasLocation(#20163,#20160)
533-
#20164=*
534-
jsdoc_type_exprs(#20164,5,#20159,1,"Menu")
535-
hasLocation(#20164,#20160)
536-
jsdoc_has_new_parameter(#20145)
530+
jsdoc_type_exprs(#20163,5,#20161,0,"goog")
531+
#20164=@"loc,{#10000},11,26,11,29"
532+
locations_default(#20164,#10000,11,26,11,29)
533+
hasLocation(#20163,#20164)
537534
#20165=*
538-
jsdoc_tags(#20165,"param",#20117,4,"@param")
539-
#20166=@"loc,{#10000},12,5,12,10"
540-
locations_default(#20166,#10000,12,5,12,10)
535+
jsdoc_type_exprs(#20165,5,#20161,1,"ui")
536+
#20166=@"loc,{#10000},11,31,11,32"
537+
locations_default(#20166,#10000,11,31,11,32)
541538
hasLocation(#20165,#20166)
542-
jsdoc_tag_names(#20165,"var_args")
543539
#20167=*
544-
jsdoc_type_exprs(#20167,14,#20165,0,"...number")
545-
#20168=@"loc,{#10000},12,13,12,21"
546-
locations_default(#20168,#10000,12,13,12,21)
540+
jsdoc_type_exprs(#20167,5,#20159,1,"Menu")
541+
#20168=@"loc,{#10000},11,34,11,37"
542+
locations_default(#20168,#10000,11,34,11,37)
547543
hasLocation(#20167,#20168)
544+
jsdoc_has_new_parameter(#20145)
548545
#20169=*
549-
jsdoc_type_exprs(#20169,5,#20167,0,"number")
550-
#20170=@"loc,{#10000},12,16,12,21"
551-
locations_default(#20170,#10000,12,16,12,21)
546+
jsdoc_tags(#20169,"param",#20117,4,"@param")
547+
#20170=@"loc,{#10000},12,5,12,10"
548+
locations_default(#20170,#10000,12,5,12,10)
552549
hasLocation(#20169,#20170)
550+
jsdoc_tag_names(#20169,"var_args")
553551
#20171=*
554-
jsdoc(#20171,"",#20010)
555-
hasLocation(#20171,#20011)
556-
#20172=*
557-
jsdoc_tags(#20172,"param",#20171,0,"@param")
558-
#20173=@"loc,{#10000},15,4,15,9"
559-
locations_default(#20173,#10000,15,4,15,9)
560-
hasLocation(#20172,#20173)
561-
#20174=*
562-
jsdoc_errors(#20174,#20172,"Missing or invalid tag name","Missing ... ag name")
552+
jsdoc_type_exprs(#20171,14,#20169,0,"...number")
553+
#20172=@"loc,{#10000},12,13,12,21"
554+
locations_default(#20172,#10000,12,13,12,21)
555+
hasLocation(#20171,#20172)
556+
#20173=*
557+
jsdoc_type_exprs(#20173,5,#20171,0,"number")
558+
#20174=@"loc,{#10000},12,16,12,21"
559+
locations_default(#20174,#10000,12,16,12,21)
560+
hasLocation(#20173,#20174)
563561
#20175=*
564-
jsdoc_tags(#20175,"param",#20171,1,"@param")
565-
#20176=@"loc,{#10000},16,4,16,9"
566-
locations_default(#20176,#10000,16,4,16,9)
567-
hasLocation(#20175,#20176)
568-
jsdoc_tag_names(#20175,"x")
569-
#20177=*
570-
jsdoc(#20177,"",#20012)
571-
hasLocation(#20177,#20013)
562+
jsdoc(#20175,"",#20010)
563+
hasLocation(#20175,#20011)
564+
#20176=*
565+
jsdoc_tags(#20176,"param",#20175,0,"@param")
566+
#20177=@"loc,{#10000},15,4,15,9"
567+
locations_default(#20177,#10000,15,4,15,9)
568+
hasLocation(#20176,#20177)
572569
#20178=*
573-
jsdoc_tags(#20178,"",#20177,0,"@")
574-
#20179=@"loc,{#10000},20,4,20,4"
575-
locations_default(#20179,#10000,20,4,20,4)
576-
hasLocation(#20178,#20179)
577-
jsdoc_tag_descriptions(#20178,"{link a}")
578-
#20180=*
579-
jsdoc_errors(#20180,#20178,"Missing or invalid title","Missing ... d title")
570+
jsdoc_errors(#20178,#20176,"Missing or invalid tag name","Missing ... ag name")
571+
#20179=*
572+
jsdoc_tags(#20179,"param",#20175,1,"@param")
573+
#20180=@"loc,{#10000},16,4,16,9"
574+
locations_default(#20180,#10000,16,4,16,9)
575+
hasLocation(#20179,#20180)
576+
jsdoc_tag_names(#20179,"x")
580577
#20181=*
581-
jsdoc(#20181,"",#20014)
582-
hasLocation(#20181,#20015)
578+
jsdoc(#20181,"",#20012)
579+
hasLocation(#20181,#20013)
583580
#20182=*
584-
jsdoc_tags(#20182,"typedef",#20181,0,"@typedef")
585-
#20183=@"loc,{#10000},24,4,24,11"
586-
locations_default(#20183,#10000,24,4,24,11)
581+
jsdoc_tags(#20182,"",#20181,0,"@")
582+
#20183=@"loc,{#10000},20,4,20,4"
583+
locations_default(#20183,#10000,20,4,20,4)
587584
hasLocation(#20182,#20183)
588-
jsdoc_tag_descriptions(#20182,"{a}")
585+
jsdoc_tag_descriptions(#20182,"{link a}")
589586
#20184=*
590-
jsdoc_errors(#20184,#20182,"Missing or invalid tag type","Missing ... ag type")
587+
jsdoc_errors(#20184,#20182,"Missing or invalid title","Missing ... d title")
591588
#20185=*
592-
jsdoc(#20185,"[resize description]",#20016)
593-
hasLocation(#20185,#20017)
589+
jsdoc(#20185,"",#20014)
590+
hasLocation(#20185,#20015)
594591
#20186=*
595-
jsdoc_tags(#20186,"param",#20185,0,"@param")
596-
#20187=@"loc,{#10000},30,4,30,9"
597-
locations_default(#20187,#10000,30,4,30,9)
592+
jsdoc_tags(#20186,"typedef",#20185,0,"@typedef")
593+
#20187=@"loc,{#10000},24,4,24,11"
594+
locations_default(#20187,#10000,24,4,24,11)
598595
hasLocation(#20186,#20187)
599-
jsdoc_tag_descriptions(#20186,"[description]
600-
")
601-
jsdoc_tag_names(#20186,"w")
596+
jsdoc_tag_descriptions(#20186,"{a}")
602597
#20188=*
603-
jsdoc_type_exprs(#20188,10,#20186,0,"[type]")
604-
#20189=@"loc,{#10000},30,13,30,18"
605-
locations_default(#20189,#10000,30,13,30,18)
606-
hasLocation(#20188,#20189)
598+
jsdoc_errors(#20188,#20186,"Missing or invalid tag type","Missing ... ag type")
599+
#20189=*
600+
jsdoc(#20189,"[resize description]",#20016)
601+
hasLocation(#20189,#20017)
607602
#20190=*
608-
jsdoc_type_exprs(#20190,5,#20188,0,"type")
609-
#20191=@"loc,{#10000},30,14,30,17"
610-
locations_default(#20191,#10000,30,14,30,17)
603+
jsdoc_tags(#20190,"param",#20189,0,"@param")
604+
#20191=@"loc,{#10000},30,4,30,9"
605+
locations_default(#20191,#10000,30,4,30,9)
611606
hasLocation(#20190,#20191)
607+
jsdoc_tag_descriptions(#20190,"[description]
608+
")
609+
jsdoc_tag_names(#20190,"w")
612610
#20192=*
613-
jsdoc_tags(#20192,"param",#20185,1,"@param")
614-
#20193=@"loc,{#10000},31,4,31,9"
615-
locations_default(#20193,#10000,31,4,31,9)
611+
jsdoc_type_exprs(#20192,10,#20190,0,"[type]")
612+
#20193=@"loc,{#10000},30,13,30,18"
613+
locations_default(#20193,#10000,30,13,30,18)
616614
hasLocation(#20192,#20193)
617-
jsdoc_tag_descriptions(#20192,"[description]
618-
")
619615
#20194=*
620-
jsdoc_tags(#20194,"return",#20185,2,"@return")
621-
#20195=@"loc,{#10000},32,4,32,10"
622-
locations_default(#20195,#10000,32,4,32,10)
616+
jsdoc_type_exprs(#20194,5,#20192,0,"type")
617+
#20195=@"loc,{#10000},30,14,30,17"
618+
locations_default(#20195,#10000,30,14,30,17)
623619
hasLocation(#20194,#20195)
624-
jsdoc_tag_descriptions(#20194,"[description]")
625620
#20196=*
626-
jsdoc_type_exprs(#20196,10,#20194,0,"[type]")
627-
#20197=@"loc,{#10000},32,13,32,18"
628-
locations_default(#20197,#10000,32,13,32,18)
621+
jsdoc_tags(#20196,"param",#20189,1,"@param")
622+
#20197=@"loc,{#10000},31,4,31,9"
623+
locations_default(#20197,#10000,31,4,31,9)
629624
hasLocation(#20196,#20197)
625+
jsdoc_tag_descriptions(#20196,"[description]
626+
")
630627
#20198=*
631-
jsdoc_type_exprs(#20198,5,#20196,0,"type")
632-
#20199=@"loc,{#10000},32,14,32,17"
633-
locations_default(#20199,#10000,32,14,32,17)
628+
jsdoc_tags(#20198,"return",#20189,2,"@return")
629+
#20199=@"loc,{#10000},32,4,32,10"
630+
locations_default(#20199,#10000,32,4,32,10)
634631
hasLocation(#20198,#20199)
632+
jsdoc_tag_descriptions(#20198,"[description]")
635633
#20200=*
636-
jsdoc(#20200,"",#20018)
637-
hasLocation(#20200,#20019)
638-
#20201=*
639-
jsdoc_tags(#20201,"exports",#20200,0,"@exports")
640-
#20202=@"loc,{#10000},36,3,36,10"
641-
locations_default(#20202,#10000,36,3,36,10)
642-
hasLocation(#20201,#20202)
643-
jsdoc_tag_descriptions(#20201,"R
644-
")
645-
#20203=*
646-
jsdoc(#20203,"",#20020)
647-
hasLocation(#20203,#20021)
634+
jsdoc_type_exprs(#20200,10,#20198,0,"[type]")
635+
#20201=@"loc,{#10000},32,13,32,18"
636+
locations_default(#20201,#10000,32,13,32,18)
637+
hasLocation(#20200,#20201)
638+
#20202=*
639+
jsdoc_type_exprs(#20202,5,#20200,0,"type")
640+
#20203=@"loc,{#10000},32,14,32,17"
641+
locations_default(#20203,#10000,32,14,32,17)
642+
hasLocation(#20202,#20203)
648643
#20204=*
649-
jsdoc_tags(#20204,"typedef",#20203,0,"@typedef")
650-
#20205=@"loc,{#10000},41,4,41,11"
651-
locations_default(#20205,#10000,41,4,41,11)
652-
hasLocation(#20204,#20205)
653-
#20206=*
654-
jsdoc_type_exprs(#20206,9,#20204,0,"{0: number}")
655-
#20207=@"loc,{#10000},41,14,41,24"
656-
locations_default(#20207,#10000,41,14,41,24)
657-
hasLocation(#20206,#20207)
658-
jsdoc_record_field_name(#20206,0,"0")
644+
jsdoc(#20204,"",#20018)
645+
hasLocation(#20204,#20019)
646+
#20205=*
647+
jsdoc_tags(#20205,"exports",#20204,0,"@exports")
648+
#20206=@"loc,{#10000},36,3,36,10"
649+
locations_default(#20206,#10000,36,3,36,10)
650+
hasLocation(#20205,#20206)
651+
jsdoc_tag_descriptions(#20205,"R
652+
")
653+
#20207=*
654+
jsdoc(#20207,"",#20020)
655+
hasLocation(#20207,#20021)
659656
#20208=*
660-
jsdoc_type_exprs(#20208,5,#20206,0,"number")
661-
#20209=@"loc,{#10000},41,18,41,23"
662-
locations_default(#20209,#10000,41,18,41,23)
657+
jsdoc_tags(#20208,"typedef",#20207,0,"@typedef")
658+
#20209=@"loc,{#10000},41,4,41,11"
659+
locations_default(#20209,#10000,41,4,41,11)
663660
hasLocation(#20208,#20209)
661+
#20210=*
662+
jsdoc_type_exprs(#20210,9,#20208,0,"{0: number}")
663+
#20211=@"loc,{#10000},41,14,41,24"
664+
locations_default(#20211,#10000,41,14,41,24)
665+
hasLocation(#20210,#20211)
666+
jsdoc_record_field_name(#20210,0,"0")
667+
#20212=*
668+
jsdoc_type_exprs(#20212,5,#20210,0,"number")
669+
#20213=@"loc,{#10000},41,18,41,23"
670+
locations_default(#20213,#10000,41,18,41,23)
671+
hasLocation(#20212,#20213)
664672
toplevels(#20001,0)
665-
#20210=@"loc,{#10000},1,1,43,0"
666-
locations_default(#20210,#10000,1,1,43,0)
667-
hasLocation(#20001,#20210)
668-
#20211=*
669-
entry_cfg_node(#20211,#20001)
670-
#20212=@"loc,{#10000},1,1,1,0"
671-
locations_default(#20212,#10000,1,1,1,0)
672-
hasLocation(#20211,#20212)
673-
#20213=*
674-
exit_cfg_node(#20213,#20001)
675-
hasLocation(#20213,#20105)
676-
successor(#20211,#20213)
673+
#20214=@"loc,{#10000},1,1,43,0"
674+
locations_default(#20214,#10000,1,1,43,0)
675+
hasLocation(#20001,#20214)
676+
#20215=*
677+
entry_cfg_node(#20215,#20001)
678+
#20216=@"loc,{#10000},1,1,1,0"
679+
locations_default(#20216,#10000,1,1,1,0)
680+
hasLocation(#20215,#20216)
681+
#20217=*
682+
exit_cfg_node(#20217,#20001)
683+
hasLocation(#20217,#20105)
684+
successor(#20215,#20217)
677685
numlines(#10000,42,0,37)
678686
filetype(#10000,"javascript")
Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
| bar.js:5:14:5:18 | x | x |
1+
| bar.js:5:14:5:14 | x | x |
22
| bar.js:5:14:5:18 | x.Foo | ns.very.long.namespace.Foo |
3-
| bar.js:12:14:12:21 | iife | iife |
3+
| bar.js:12:14:12:17 | iife | iife |
44
| bar.js:12:14:12:21 | iife.Foo | IIFE.Foo |
5-
| closure.js:8:12:8:28 | goog | goog |
6-
| closure.js:8:12:8:28 | goog.net | goog.net |
5+
| closure.js:8:12:8:15 | goog | goog |
6+
| closure.js:8:12:8:19 | goog.net | goog.net |
77
| closure.js:8:12:8:28 | goog.net.SomeType | goog.net.SomeType |
8-
| closure.js:9:12:9:23 | net | net |
8+
| closure.js:9:12:9:14 | net | net |
99
| closure.js:9:12:9:23 | net.SomeType | goog.net.SomeType |
1010
| closure.js:10:12:10:19 | SomeType | goog.net.SomeType |

0 commit comments

Comments
 (0)