@@ -845,32 +845,35 @@ function prune(graph1_a::SyntaxGraph, entrypoints_a::Vector{NodeId})
845845
846846 # Resolve provenance. Tricky to avoid dangling `.source` references.
847847 resolved_sources = Dict {NodeId, SourceAttrType} () # graph1 id => graph2 src
848- function get_resolved! (id1:: NodeId )
849- out = get (resolved_sources, id1, nothing )
850- if isnothing (out)
851- src1 = graph1. source[id1]
852- out = if haskey (map12, src1)
853- map12[src1]
854- elseif src1 isa NodeId
855- get_resolved! (src1)
856- elseif src1 isa Tuple
857- map (get_resolved!, src1)
858- else
859- src1
860- end
861- resolved_sources[id1] = out
862- end
863- return out
864- end
865848
866849 for (n2, n1) in enumerate (nodes1)
867- graph2. source[n2] = get_resolved ! (n1)
850+ graph2. source[n2] = _prune_get_resolved ! (n1, graph1, map12, resolved_sources )
868851 end
869852
870853 # The first n entries in nodes1 were our entrypoints, unique from unaliasing
871854 return SyntaxList (graph2, 1 : length (entrypoints))
872855end
873856
857+ function _prune_get_resolved! (id1:: NodeId , graph1:: SyntaxGraph ,
858+ map12:: Dict{NodeId, Int} ,
859+ resolved_sources:: Dict{NodeId, SourceAttrType} )
860+ out = get (resolved_sources, id1, nothing )
861+ if isnothing (out)
862+ src1 = graph1. source[id1]
863+ out = if haskey (map12, src1)
864+ map12[src1]
865+ elseif src1 isa NodeId
866+ _prune_get_resolved! (src1, graph1, map12, resolved_sources)
867+ elseif src1 isa Tuple
868+ map (s -> _prune_get_resolved! (s, graph1, map12, resolved_sources), src1)
869+ else
870+ src1
871+ end
872+ resolved_sources[id1] = out
873+ end
874+ return out
875+ end
876+
874877"""
875878Give each descendent of `st` a `parent::NodeId` attribute.
876879"""
@@ -1092,47 +1095,49 @@ function _stm_assigns(p, st_rhs_expr; assigns=Expr(:block))
10921095end
10931096
10941097# Check for correct pattern syntax. Not needed outside of development.
1095- function _stm_check_usage (pats:: Expr )
1096- function _stm_check_pattern (p; syms= Set {Symbol} ())
1097- if Meta. isexpr (p, :(... ), 1 )
1098- p = p. args[1 ]
1099- @assert (p isa Symbol, " Expected symbol before `...` in $p " )
1100- end
1101- if p isa Symbol
1102- # No support for duplicate syms for now (user is either looking for
1103- # some form of equality we don't implement, or they made a mistake)
1104- dup = p in syms && p != = :_
1105- push! (syms, p)
1106- @assert (! dup, " invalid duplicate non-underscore identifier $p " )
1107- return nothing
1108- elseif Meta. isexpr (p, :vect )
1109- @assert (length (p. args) === 1 ,
1110- " use spaces, not commas, in @stm []-patterns" )
1111- elseif Meta. isexpr (p, :hcat )
1112- @assert (length (p. args) >= 2 )
1113- elseif Meta. isexpr (p, :vcat )
1114- p = _stm_vcat_to_hcat (p)
1115- @assert (length (p. args) >= 2 )
1116- else
1117- @assert (false , " malformed pattern $p " )
1118- end
1119- @assert (count (x-> Meta. isexpr (x, :(... )), p. args[2 : end ]) <= 1 ,
1120- " Multiple `...` in a pattern is ambiguous" )
1121-
1122- # This exact `K"kind"` syntax is not necessary since the kind can't be
1123- # provided by a variable, but requiring [K"kinds"] is consistent with
1124- # `@ast` and allows us to implement list matching later.
1125- @assert (Meta. isexpr (p. args[1 ], :macrocall , 3 ) &&
1126- p. args[1 ]. args[1 ] === Symbol (" @K_str" ) &&
1127- p. args[1 ]. args[3 ] isa String, " first pattern elt must be K\"\" " )
1128-
1129- for subp in p. args[2 : end ]
1130- _stm_check_pattern (subp; syms)
1131- end
1098+ function _stm_check_pattern (p, syms:: Set{Symbol} )
1099+ if Meta. isexpr (p, :(... ), 1 )
1100+ p = p. args[1 ]
1101+ @assert (p isa Symbol, " Expected symbol before `...` in $p " )
11321102 end
1103+ if p isa Symbol
1104+ # No support for duplicate syms for now (user is either looking for
1105+ # some form of equality we don't implement, or they made a mistake)
1106+ dup = p in syms && p != = :_
1107+ push! (syms, p)
1108+ @assert (! dup, " invalid duplicate non-underscore identifier $p " )
1109+ return nothing
1110+ elseif Meta. isexpr (p, :vect )
1111+ @assert (length (p. args) === 1 ,
1112+ " use spaces, not commas, in @stm []-patterns" )
1113+ elseif Meta. isexpr (p, :hcat )
1114+ @assert (length (p. args) >= 2 )
1115+ elseif Meta. isexpr (p, :vcat )
1116+ p = _stm_vcat_to_hcat (p)
1117+ @assert (length (p. args) >= 2 )
1118+ else
1119+ @assert (false , " malformed pattern $p " )
1120+ end
1121+ @assert (count (x-> Meta. isexpr (x, :(... )), p. args[2 : end ]) <= 1 ,
1122+ " Multiple `...` in a pattern is ambiguous" )
1123+
1124+ # This exact `K"kind"` syntax is not necessary since the kind can't be
1125+ # provided by a variable, but requiring [K"kinds"] is consistent with
1126+ # `@ast` and allows us to implement list matching later.
1127+ @assert (Meta. isexpr (p. args[1 ], :macrocall , 3 ) &&
1128+ p. args[1 ]. args[1 ] === Symbol (" @K_str" ) &&
1129+ p. args[1 ]. args[3 ] isa String, " first pattern elt must be K\"\" " )
1130+
1131+ for subp in p. args[2 : end ]
1132+ _stm_check_pattern (subp, syms)
1133+ end
1134+ return nothing
1135+ end
11331136
1137+ function _stm_check_usage (pats:: Expr )
11341138 @assert Meta. isexpr (pats, :block ) " Usage: @stm st begin; ...; end"
1135- for pcr in filter (e-> ! isa (e, LineNumberNode), pats. args)
1139+ for pcr in pats. args
1140+ pcr isa LineNumberNode && continue
11361141 @assert (Meta. isexpr (pcr, :(-> ), 2 ), " Expected pat -> res, got malformed case: $pcr " )
11371142 if Meta. isexpr (pcr. args[1 ], :tuple )
11381143 @assert (length (pcr. args[1 ]. args) === 2 ,
@@ -1144,7 +1149,7 @@ function _stm_check_usage(pats::Expr)
11441149 else
11451150 p = pcr. args[1 ]
11461151 end
1147- _stm_check_pattern (p)
1152+ _stm_check_pattern (p, Set {Symbol} () )
11481153 end
11491154end
11501155
0 commit comments