diff --git a/javascript/extractor/src/com/semmle/jcorn/flow/FlowParser.java b/javascript/extractor/src/com/semmle/jcorn/flow/FlowParser.java index 7f6b815bd82..2027e6f29c3 100644 --- a/javascript/extractor/src/com/semmle/jcorn/flow/FlowParser.java +++ b/javascript/extractor/src/com/semmle/jcorn/flow/FlowParser.java @@ -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 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(); diff --git a/javascript/extractor/tests/flow/input/importNonTypeInDeclaredModule.js b/javascript/extractor/tests/flow/input/importNonTypeInDeclaredModule.js new file mode 100644 index 00000000000..1fd4359943d --- /dev/null +++ b/javascript/extractor/tests/flow/input/importNonTypeInDeclaredModule.js @@ -0,0 +1,7 @@ +declare module "m1" { + import { + T1, + T2 + } from "m2" +} + \ No newline at end of file diff --git a/javascript/extractor/tests/flow/input/importType.js b/javascript/extractor/tests/flow/input/importType.js index 00c1426201f..51d0f9e962f 100644 --- a/javascript/extractor/tests/flow/input/importType.js +++ b/javascript/extractor/tests/flow/input/importType.js @@ -1,2 +1,3 @@ import { type, type t1, typeof t2 } from 'm'; import { type t } from 'n'; +import type { t } from 'o'; \ No newline at end of file diff --git a/javascript/extractor/tests/flow/input/importTypeInDeclaredModule.js b/javascript/extractor/tests/flow/input/importTypeInDeclaredModule.js new file mode 100644 index 00000000000..5ceb245fb12 --- /dev/null +++ b/javascript/extractor/tests/flow/input/importTypeInDeclaredModule.js @@ -0,0 +1,11 @@ +declare module "m1" { + import type { + T1, + T2 + } from "m2" + import typeof { + T3, + T4 + } from "m3" +} + \ No newline at end of file diff --git a/javascript/extractor/tests/flow/output/trap/importNonTypeInDeclaredModule.js.trap b/javascript/extractor/tests/flow/output/trap/importNonTypeInDeclaredModule.js.trap new file mode 100644 index 00000000000..21e3081e298 --- /dev/null +++ b/javascript/extractor/tests/flow/output/trap/importNonTypeInDeclaredModule.js.trap @@ -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") diff --git a/javascript/extractor/tests/flow/output/trap/importType.js.trap b/javascript/extractor/tests/flow/output/trap/importType.js.trap index aaafc65c9be..c51c8058a27 100644 --- a/javascript/extractor/tests/flow/output/trap/importType.js.trap +++ b/javascript/extractor/tests/flow/output/trap/importType.js.trap @@ -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") diff --git a/javascript/extractor/tests/flow/output/trap/importTypeInDeclaredModule.js.trap b/javascript/extractor/tests/flow/output/trap/importTypeInDeclaredModule.js.trap new file mode 100644 index 00000000000..b04016f5951 --- /dev/null +++ b/javascript/extractor/tests/flow/output/trap/importTypeInDeclaredModule.js.trap @@ -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")