JS: support additional import statements for Flow

This commit is contained in:
Esben Sparre Andreasen
2019-01-03 15:48:16 +01:00
parent eabc674bb3
commit c6f9a043ca
7 changed files with 457 additions and 104 deletions

View File

@@ -21,6 +21,7 @@ import com.semmle.js.ast.Expression;
import com.semmle.js.ast.ExpressionStatement;
import com.semmle.js.ast.FieldDefinition;
import com.semmle.js.ast.Identifier;
import com.semmle.js.ast.ImportDeclaration;
import com.semmle.js.ast.ImportSpecifier;
import com.semmle.js.ast.MethodDefinition;
import com.semmle.js.ast.Node;
@@ -226,30 +227,21 @@ public class FlowParser extends ESNextParser {
this.expect(TokenType.braceL);
while (this.type != TokenType.braceR) {
Position stmtStart = startLoc;
if (this.eat(TokenType._import)) {
this.flowParseDeclareImport(stmtStart);
} else {
// todo: declare check
this.next();
if (this.eatContextual("declare")) {
this.flowParseDeclare(stmtStart);
} else if (this.eat(TokenType._import)) {
if (peekAtSpecialFlowImportSpecifier() == null) {
this.raise(stmtStart,
"Imports within a `declare module` body must always be `import type` or `import typeof`.");
}
this.parseImportRest(new SourceLocation(stmtStart));
} else {
unexpected();
}
}
this.expect(TokenType.braceR);
}
private void flowParseDeclareImport(Position stmtStart) {
String kind = flowParseImportSpecifiers();
if (kind == null) {
this.raise(stmtStart, "Imports within a `declare module` body must always be `import type` or `import typeof`.");
}
this.expect(TokenType.name);
this.expectContextual("from");
this.expect(TokenType.string);
this.semicolon();
}
private void flowParseDeclareModuleExports() {
this.expectContextual("module");
this.expect(TokenType.dot);
@@ -1004,12 +996,7 @@ public class FlowParser extends ESNextParser {
}
private String flowParseImportSpecifiers() {
String kind = null;
if (this.type == TokenType._typeof) {
kind = "typeof";
} else if (this.isContextual("type")) {
kind = "type";
}
String kind = peekAtSpecialFlowImportSpecifier();
if (kind != null) {
String lh = lookahead(4);
if (!lh.isEmpty()) {
@@ -1022,6 +1009,16 @@ public class FlowParser extends ESNextParser {
return kind;
}
private String peekAtSpecialFlowImportSpecifier() {
String kind = null;
if (this.type == TokenType._typeof) {
kind = "typeof";
} else if (this.isContextual("type")) {
kind = "type";
}
return kind;
}
@Override
protected List<ImportSpecifier> parseImportSpecifiers() {
String kind = null;
@@ -1037,7 +1034,7 @@ public class FlowParser extends ESNextParser {
@Override
protected ImportSpecifier parseImportSpecifier() {
if (this.type == TokenType._typeof || this.isContextual("type")) {
if (peekAtSpecialFlowImportSpecifier() != null) {
String lh = lookahead(2);
if (lh.charAt(0) == ',' || lh.charAt(0) == '}' || lh.equals("as"))
return super.parseImportSpecifier();

View File

@@ -0,0 +1,7 @@
declare module "m1" {
import {
T1,
T2
} from "m2"
}

View File

@@ -1,2 +1,3 @@
import { type, type t1, typeof t2 } from 'm';
import { type t } from 'n';
import type { t } from 'o';

View File

@@ -0,0 +1,11 @@
declare module "m1" {
import type {
T1,
T2
} from "m2"
import typeof {
T3,
T4
} from "m3"
}

View File

@@ -0,0 +1,69 @@
#10000=@"/importNonTypeInDeclaredModule.js;sourcefile"
files(#10000,"/importNonTypeInDeclaredModule.js","importNonTypeInDeclaredModule","js",0)
#10001=@"/;folder"
folders(#10001,"/","")
containerparent(#10001,#10000)
#10002=@"loc,{#10000},0,0,0,0"
locations_default(#10002,#10000,0,0,0,0)
hasLocation(#10000,#10002)
#20000=@"global_scope"
scopes(#20000,0)
#20001=@"script;{#10000},1,1"
toplevels(#20001,0)
#20002=@"loc,{#10000},1,1,1,1"
locations_default(#20002,#10000,1,1,1,1)
hasLocation(#20001,#20002)
#20003=*
jsParseErrors(#20003,#20001,"Error: Imports within a `declare module` body must always be `import type` or `import typeof`."," import {
")
#20004=@"loc,{#10000},2,3,2,3"
locations_default(#20004,#10000,2,3,2,3)
hasLocation(#20003,#20004)
#20005=*
lines(#20005,#20001,"declare module ""m1"" {","
")
#20006=@"loc,{#10000},1,1,1,21"
locations_default(#20006,#10000,1,1,1,21)
hasLocation(#20005,#20006)
#20007=*
lines(#20007,#20001," import {","
")
#20008=@"loc,{#10000},2,1,2,10"
locations_default(#20008,#10000,2,1,2,10)
hasLocation(#20007,#20008)
indentation(#10000,2," ",2)
#20009=*
lines(#20009,#20001," T1,","
")
#20010=@"loc,{#10000},3,1,3,7"
locations_default(#20010,#10000,3,1,3,7)
hasLocation(#20009,#20010)
indentation(#10000,3," ",4)
#20011=*
lines(#20011,#20001," T2","
")
#20012=@"loc,{#10000},4,1,4,6"
locations_default(#20012,#10000,4,1,4,6)
hasLocation(#20011,#20012)
indentation(#10000,4," ",4)
#20013=*
lines(#20013,#20001," } from ""m2""","
")
#20014=@"loc,{#10000},5,1,5,13"
locations_default(#20014,#10000,5,1,5,13)
hasLocation(#20013,#20014)
indentation(#10000,5," ",2)
#20015=*
lines(#20015,#20001,"}","
")
#20016=@"loc,{#10000},6,1,6,1"
locations_default(#20016,#10000,6,1,6,1)
hasLocation(#20015,#20016)
#20017=*
lines(#20017,#20001," ","")
#20018=@"loc,{#10000},7,1,7,2"
locations_default(#20018,#10000,7,1,7,2)
hasLocation(#20017,#20018)
numlines(#20001,7,0,0)
numlines(#10000,7,0,0)
filetype(#10000,"javascript")

View File

@@ -10,8 +10,8 @@ hasLocation(#10000,#10002)
scopes(#20000,0)
#20001=@"script;{#10000},1,1"
toplevels(#20001,0)
#20002=@"loc,{#10000},1,1,3,0"
locations_default(#20002,#10000,1,1,3,0)
#20002=@"loc,{#10000},1,1,3,27"
locations_default(#20002,#10000,1,1,3,27)
hasLocation(#20001,#20002)
#20003=@"module;{#10000},1,1"
scopes(#20003,3)
@@ -73,123 +73,168 @@ lines(#20016,#20001,"import { type t } from 'n';","
#20017=@"loc,{#10000},2,1,2,27"
locations_default(#20017,#10000,2,1,2,27)
hasLocation(#20016,#20017)
numlines(#20001,2,2,0)
#20018=*
tokeninfo(#20018,7,#20001,0,"import")
#20019=@"loc,{#10000},1,1,1,6"
locations_default(#20019,#10000,1,1,1,6)
lines(#20018,#20001,"import type { t } from 'o';","")
#20019=@"loc,{#10000},3,1,3,27"
locations_default(#20019,#10000,3,1,3,27)
hasLocation(#20018,#20019)
numlines(#20001,3,3,0)
#20020=*
tokeninfo(#20020,8,#20001,1,"{")
#20021=@"loc,{#10000},1,8,1,8"
locations_default(#20021,#10000,1,8,1,8)
tokeninfo(#20020,7,#20001,0,"import")
#20021=@"loc,{#10000},1,1,1,6"
locations_default(#20021,#10000,1,1,1,6)
hasLocation(#20020,#20021)
#20022=*
tokeninfo(#20022,6,#20001,2,"type")
hasLocation(#20022,#20012)
#20023=*
tokeninfo(#20023,8,#20001,3,",")
#20024=@"loc,{#10000},1,14,1,14"
locations_default(#20024,#10000,1,14,1,14)
hasLocation(#20023,#20024)
tokeninfo(#20022,8,#20001,1,"{")
#20023=@"loc,{#10000},1,8,1,8"
locations_default(#20023,#10000,1,8,1,8)
hasLocation(#20022,#20023)
#20024=*
tokeninfo(#20024,6,#20001,2,"type")
hasLocation(#20024,#20012)
#20025=*
tokeninfo(#20025,6,#20001,4,"type")
#20026=@"loc,{#10000},1,16,1,19"
locations_default(#20026,#10000,1,16,1,19)
tokeninfo(#20025,8,#20001,3,",")
#20026=@"loc,{#10000},1,14,1,14"
locations_default(#20026,#10000,1,14,1,14)
hasLocation(#20025,#20026)
#20027=*
tokeninfo(#20027,6,#20001,5,"t1")
#20028=@"loc,{#10000},1,21,1,22"
locations_default(#20028,#10000,1,21,1,22)
tokeninfo(#20027,6,#20001,4,"type")
#20028=@"loc,{#10000},1,16,1,19"
locations_default(#20028,#10000,1,16,1,19)
hasLocation(#20027,#20028)
#20029=*
tokeninfo(#20029,8,#20001,6,",")
#20030=@"loc,{#10000},1,23,1,23"
locations_default(#20030,#10000,1,23,1,23)
tokeninfo(#20029,6,#20001,5,"t1")
#20030=@"loc,{#10000},1,21,1,22"
locations_default(#20030,#10000,1,21,1,22)
hasLocation(#20029,#20030)
#20031=*
tokeninfo(#20031,7,#20001,7,"typeof")
#20032=@"loc,{#10000},1,25,1,30"
locations_default(#20032,#10000,1,25,1,30)
tokeninfo(#20031,8,#20001,6,",")
#20032=@"loc,{#10000},1,23,1,23"
locations_default(#20032,#10000,1,23,1,23)
hasLocation(#20031,#20032)
#20033=*
tokeninfo(#20033,6,#20001,8,"t2")
#20034=@"loc,{#10000},1,32,1,33"
locations_default(#20034,#10000,1,32,1,33)
tokeninfo(#20033,7,#20001,7,"typeof")
#20034=@"loc,{#10000},1,25,1,30"
locations_default(#20034,#10000,1,25,1,30)
hasLocation(#20033,#20034)
#20035=*
tokeninfo(#20035,8,#20001,9,"}")
#20036=@"loc,{#10000},1,35,1,35"
locations_default(#20036,#10000,1,35,1,35)
tokeninfo(#20035,6,#20001,8,"t2")
#20036=@"loc,{#10000},1,32,1,33"
locations_default(#20036,#10000,1,32,1,33)
hasLocation(#20035,#20036)
#20037=*
tokeninfo(#20037,6,#20001,10,"from")
#20038=@"loc,{#10000},1,37,1,40"
locations_default(#20038,#10000,1,37,1,40)
tokeninfo(#20037,8,#20001,9,"}")
#20038=@"loc,{#10000},1,35,1,35"
locations_default(#20038,#10000,1,35,1,35)
hasLocation(#20037,#20038)
#20039=*
tokeninfo(#20039,4,#20001,11,"'m'")
hasLocation(#20039,#20010)
#20040=*
tokeninfo(#20040,8,#20001,12,";")
#20041=@"loc,{#10000},1,45,1,45"
locations_default(#20041,#10000,1,45,1,45)
hasLocation(#20040,#20041)
tokeninfo(#20039,6,#20001,10,"from")
#20040=@"loc,{#10000},1,37,1,40"
locations_default(#20040,#10000,1,37,1,40)
hasLocation(#20039,#20040)
#20041=*
tokeninfo(#20041,4,#20001,11,"'m'")
hasLocation(#20041,#20010)
#20042=*
tokeninfo(#20042,7,#20001,13,"import")
#20043=@"loc,{#10000},2,1,2,6"
locations_default(#20043,#10000,2,1,2,6)
tokeninfo(#20042,8,#20001,12,";")
#20043=@"loc,{#10000},1,45,1,45"
locations_default(#20043,#10000,1,45,1,45)
hasLocation(#20042,#20043)
#20044=*
tokeninfo(#20044,8,#20001,14,"{")
#20045=@"loc,{#10000},2,8,2,8"
locations_default(#20045,#10000,2,8,2,8)
tokeninfo(#20044,7,#20001,13,"import")
#20045=@"loc,{#10000},2,1,2,6"
locations_default(#20045,#10000,2,1,2,6)
hasLocation(#20044,#20045)
#20046=*
tokeninfo(#20046,6,#20001,15,"type")
#20047=@"loc,{#10000},2,10,2,13"
locations_default(#20047,#10000,2,10,2,13)
tokeninfo(#20046,8,#20001,14,"{")
#20047=@"loc,{#10000},2,8,2,8"
locations_default(#20047,#10000,2,8,2,8)
hasLocation(#20046,#20047)
#20048=*
tokeninfo(#20048,6,#20001,16,"t")
#20049=@"loc,{#10000},2,15,2,15"
locations_default(#20049,#10000,2,15,2,15)
tokeninfo(#20048,6,#20001,15,"type")
#20049=@"loc,{#10000},2,10,2,13"
locations_default(#20049,#10000,2,10,2,13)
hasLocation(#20048,#20049)
#20050=*
tokeninfo(#20050,8,#20001,17,"}")
#20051=@"loc,{#10000},2,17,2,17"
locations_default(#20051,#10000,2,17,2,17)
tokeninfo(#20050,6,#20001,16,"t")
#20051=@"loc,{#10000},2,15,2,15"
locations_default(#20051,#10000,2,15,2,15)
hasLocation(#20050,#20051)
#20052=*
tokeninfo(#20052,6,#20001,18,"from")
#20053=@"loc,{#10000},2,19,2,22"
locations_default(#20053,#10000,2,19,2,22)
tokeninfo(#20052,8,#20001,17,"}")
#20053=@"loc,{#10000},2,17,2,17"
locations_default(#20053,#10000,2,17,2,17)
hasLocation(#20052,#20053)
#20054=*
tokeninfo(#20054,4,#20001,19,"'n'")
#20055=@"loc,{#10000},2,24,2,26"
locations_default(#20055,#10000,2,24,2,26)
tokeninfo(#20054,6,#20001,18,"from")
#20055=@"loc,{#10000},2,19,2,22"
locations_default(#20055,#10000,2,19,2,22)
hasLocation(#20054,#20055)
#20056=*
tokeninfo(#20056,8,#20001,20,";")
#20057=@"loc,{#10000},2,27,2,27"
locations_default(#20057,#10000,2,27,2,27)
tokeninfo(#20056,4,#20001,19,"'n'")
#20057=@"loc,{#10000},2,24,2,26"
locations_default(#20057,#10000,2,24,2,26)
hasLocation(#20056,#20057)
#20058=*
tokeninfo(#20058,0,#20001,21,"")
#20059=@"loc,{#10000},3,1,3,0"
locations_default(#20059,#10000,3,1,3,0)
tokeninfo(#20058,8,#20001,20,";")
#20059=@"loc,{#10000},2,27,2,27"
locations_default(#20059,#10000,2,27,2,27)
hasLocation(#20058,#20059)
#20060=*
entry_cfg_node(#20060,#20001)
#20061=@"loc,{#10000},1,1,1,0"
locations_default(#20061,#10000,1,1,1,0)
tokeninfo(#20060,7,#20001,21,"import")
#20061=@"loc,{#10000},3,1,3,6"
locations_default(#20061,#10000,3,1,3,6)
hasLocation(#20060,#20061)
#20062=*
exit_cfg_node(#20062,#20001)
hasLocation(#20062,#20059)
successor(#20007,#20062)
tokeninfo(#20062,6,#20001,22,"type")
#20063=@"loc,{#10000},3,8,3,11"
locations_default(#20063,#10000,3,8,3,11)
hasLocation(#20062,#20063)
#20064=*
tokeninfo(#20064,8,#20001,23,"{")
#20065=@"loc,{#10000},3,13,3,13"
locations_default(#20065,#10000,3,13,3,13)
hasLocation(#20064,#20065)
#20066=*
tokeninfo(#20066,6,#20001,24,"t")
#20067=@"loc,{#10000},3,15,3,15"
locations_default(#20067,#10000,3,15,3,15)
hasLocation(#20066,#20067)
#20068=*
tokeninfo(#20068,8,#20001,25,"}")
#20069=@"loc,{#10000},3,17,3,17"
locations_default(#20069,#10000,3,17,3,17)
hasLocation(#20068,#20069)
#20070=*
tokeninfo(#20070,6,#20001,26,"from")
#20071=@"loc,{#10000},3,19,3,22"
locations_default(#20071,#10000,3,19,3,22)
hasLocation(#20070,#20071)
#20072=*
tokeninfo(#20072,4,#20001,27,"'o'")
#20073=@"loc,{#10000},3,24,3,26"
locations_default(#20073,#10000,3,24,3,26)
hasLocation(#20072,#20073)
#20074=*
tokeninfo(#20074,8,#20001,28,";")
#20075=@"loc,{#10000},3,27,3,27"
locations_default(#20075,#10000,3,27,3,27)
hasLocation(#20074,#20075)
#20076=*
tokeninfo(#20076,0,#20001,29,"")
#20077=@"loc,{#10000},3,28,3,27"
locations_default(#20077,#10000,3,28,3,27)
hasLocation(#20076,#20077)
#20078=*
entry_cfg_node(#20078,#20001)
#20079=@"loc,{#10000},1,1,1,0"
locations_default(#20079,#10000,1,1,1,0)
hasLocation(#20078,#20079)
#20080=*
exit_cfg_node(#20080,#20001)
hasLocation(#20080,#20077)
successor(#20007,#20080)
successor(#20011,#20007)
successor(#20060,#20011)
numlines(#10000,2,2,0)
successor(#20078,#20011)
numlines(#10000,3,3,0)
filetype(#10000,"javascript")

View File

@@ -0,0 +1,223 @@
#10000=@"/importTypeInDeclaredModule.js;sourcefile"
files(#10000,"/importTypeInDeclaredModule.js","importTypeInDeclaredModule","js",0)
#10001=@"/;folder"
folders(#10001,"/","")
containerparent(#10001,#10000)
#10002=@"loc,{#10000},0,0,0,0"
locations_default(#10002,#10000,0,0,0,0)
hasLocation(#10000,#10002)
#20000=@"global_scope"
scopes(#20000,0)
#20001=@"script;{#10000},1,1"
toplevels(#20001,0)
#20002=@"loc,{#10000},1,1,11,2"
locations_default(#20002,#10000,1,1,11,2)
hasLocation(#20001,#20002)
#20003=@"module;{#10000},1,1"
scopes(#20003,3)
scopenodes(#20001,#20003)
scopenesting(#20003,#20000)
isModule(#20001)
#20004=*
lines(#20004,#20001,"declare module ""m1"" {","
")
#20005=@"loc,{#10000},1,1,1,21"
locations_default(#20005,#10000,1,1,1,21)
hasLocation(#20004,#20005)
#20006=*
lines(#20006,#20001," import type {","
")
#20007=@"loc,{#10000},2,1,2,15"
locations_default(#20007,#10000,2,1,2,15)
hasLocation(#20006,#20007)
indentation(#10000,2," ",2)
#20008=*
lines(#20008,#20001," T1,","
")
#20009=@"loc,{#10000},3,1,3,7"
locations_default(#20009,#10000,3,1,3,7)
hasLocation(#20008,#20009)
indentation(#10000,3," ",4)
#20010=*
lines(#20010,#20001," T2","
")
#20011=@"loc,{#10000},4,1,4,6"
locations_default(#20011,#10000,4,1,4,6)
hasLocation(#20010,#20011)
indentation(#10000,4," ",4)
#20012=*
lines(#20012,#20001," } from ""m2""","
")
#20013=@"loc,{#10000},5,1,5,13"
locations_default(#20013,#10000,5,1,5,13)
hasLocation(#20012,#20013)
indentation(#10000,5," ",2)
#20014=*
lines(#20014,#20001," import typeof {","
")
#20015=@"loc,{#10000},6,1,6,19"
locations_default(#20015,#10000,6,1,6,19)
hasLocation(#20014,#20015)
indentation(#10000,6," ",4)
#20016=*
lines(#20016,#20001," T3,","
")
#20017=@"loc,{#10000},7,1,7,7"
locations_default(#20017,#10000,7,1,7,7)
hasLocation(#20016,#20017)
indentation(#10000,7," ",4)
#20018=*
lines(#20018,#20001," T4","
")
#20019=@"loc,{#10000},8,1,8,6"
locations_default(#20019,#10000,8,1,8,6)
hasLocation(#20018,#20019)
indentation(#10000,8," ",4)
#20020=*
lines(#20020,#20001," } from ""m3""","
")
#20021=@"loc,{#10000},9,1,9,13"
locations_default(#20021,#10000,9,1,9,13)
hasLocation(#20020,#20021)
indentation(#10000,9," ",2)
#20022=*
lines(#20022,#20001,"}","
")
#20023=@"loc,{#10000},10,1,10,1"
locations_default(#20023,#10000,10,1,10,1)
hasLocation(#20022,#20023)
#20024=*
lines(#20024,#20001," ","")
#20025=@"loc,{#10000},11,1,11,2"
locations_default(#20025,#10000,11,1,11,2)
hasLocation(#20024,#20025)
numlines(#20001,11,10,0)
#20026=*
tokeninfo(#20026,6,#20001,0,"declare")
#20027=@"loc,{#10000},1,1,1,7"
locations_default(#20027,#10000,1,1,1,7)
hasLocation(#20026,#20027)
#20028=*
tokeninfo(#20028,6,#20001,1,"module")
#20029=@"loc,{#10000},1,9,1,14"
locations_default(#20029,#10000,1,9,1,14)
hasLocation(#20028,#20029)
#20030=*
tokeninfo(#20030,4,#20001,2,"""m1""")
#20031=@"loc,{#10000},1,16,1,19"
locations_default(#20031,#10000,1,16,1,19)
hasLocation(#20030,#20031)
#20032=*
tokeninfo(#20032,8,#20001,3,"{")
#20033=@"loc,{#10000},1,21,1,21"
locations_default(#20033,#10000,1,21,1,21)
hasLocation(#20032,#20033)
#20034=*
tokeninfo(#20034,7,#20001,4,"import")
#20035=@"loc,{#10000},2,3,2,8"
locations_default(#20035,#10000,2,3,2,8)
hasLocation(#20034,#20035)
#20036=*
tokeninfo(#20036,6,#20001,5,"type")
#20037=@"loc,{#10000},2,10,2,13"
locations_default(#20037,#10000,2,10,2,13)
hasLocation(#20036,#20037)
#20038=*
tokeninfo(#20038,8,#20001,6,"{")
#20039=@"loc,{#10000},2,15,2,15"
locations_default(#20039,#10000,2,15,2,15)
hasLocation(#20038,#20039)
#20040=*
tokeninfo(#20040,6,#20001,7,"T1")
#20041=@"loc,{#10000},3,5,3,6"
locations_default(#20041,#10000,3,5,3,6)
hasLocation(#20040,#20041)
#20042=*
tokeninfo(#20042,8,#20001,8,",")
#20043=@"loc,{#10000},3,7,3,7"
locations_default(#20043,#10000,3,7,3,7)
hasLocation(#20042,#20043)
#20044=*
tokeninfo(#20044,6,#20001,9,"T2")
#20045=@"loc,{#10000},4,5,4,6"
locations_default(#20045,#10000,4,5,4,6)
hasLocation(#20044,#20045)
#20046=*
tokeninfo(#20046,8,#20001,10,"}")
#20047=@"loc,{#10000},5,3,5,3"
locations_default(#20047,#10000,5,3,5,3)
hasLocation(#20046,#20047)
#20048=*
tokeninfo(#20048,6,#20001,11,"from")
#20049=@"loc,{#10000},5,5,5,8"
locations_default(#20049,#10000,5,5,5,8)
hasLocation(#20048,#20049)
#20050=*
tokeninfo(#20050,4,#20001,12,"""m2""")
#20051=@"loc,{#10000},5,10,5,13"
locations_default(#20051,#10000,5,10,5,13)
hasLocation(#20050,#20051)
#20052=*
tokeninfo(#20052,7,#20001,13,"import")
#20053=@"loc,{#10000},6,5,6,10"
locations_default(#20053,#10000,6,5,6,10)
hasLocation(#20052,#20053)
#20054=*
tokeninfo(#20054,7,#20001,14,"typeof")
#20055=@"loc,{#10000},6,12,6,17"
locations_default(#20055,#10000,6,12,6,17)
hasLocation(#20054,#20055)
#20056=*
tokeninfo(#20056,8,#20001,15,"{")
#20057=@"loc,{#10000},6,19,6,19"
locations_default(#20057,#10000,6,19,6,19)
hasLocation(#20056,#20057)
#20058=*
tokeninfo(#20058,6,#20001,16,"T3")
#20059=@"loc,{#10000},7,5,7,6"
locations_default(#20059,#10000,7,5,7,6)
hasLocation(#20058,#20059)
#20060=*
tokeninfo(#20060,8,#20001,17,",")
#20061=@"loc,{#10000},7,7,7,7"
locations_default(#20061,#10000,7,7,7,7)
hasLocation(#20060,#20061)
#20062=*
tokeninfo(#20062,6,#20001,18,"T4")
#20063=@"loc,{#10000},8,5,8,6"
locations_default(#20063,#10000,8,5,8,6)
hasLocation(#20062,#20063)
#20064=*
tokeninfo(#20064,8,#20001,19,"}")
#20065=@"loc,{#10000},9,3,9,3"
locations_default(#20065,#10000,9,3,9,3)
hasLocation(#20064,#20065)
#20066=*
tokeninfo(#20066,6,#20001,20,"from")
#20067=@"loc,{#10000},9,5,9,8"
locations_default(#20067,#10000,9,5,9,8)
hasLocation(#20066,#20067)
#20068=*
tokeninfo(#20068,4,#20001,21,"""m3""")
#20069=@"loc,{#10000},9,10,9,13"
locations_default(#20069,#10000,9,10,9,13)
hasLocation(#20068,#20069)
#20070=*
tokeninfo(#20070,8,#20001,22,"}")
hasLocation(#20070,#20023)
#20071=*
tokeninfo(#20071,0,#20001,23,"")
#20072=@"loc,{#10000},11,3,11,2"
locations_default(#20072,#10000,11,3,11,2)
hasLocation(#20071,#20072)
#20073=*
entry_cfg_node(#20073,#20001)
#20074=@"loc,{#10000},1,1,1,0"
locations_default(#20074,#10000,1,1,1,0)
hasLocation(#20073,#20074)
#20075=*
exit_cfg_node(#20075,#20001)
hasLocation(#20075,#20072)
successor(#20073,#20075)
numlines(#10000,11,10,0)
filetype(#10000,"javascript")