@@ -16,124 +16,150 @@ trait SourceContextUtils {
1616 import global ._
1717 import definitions ._
1818
19- def contextSourceInfoChain (ctx : Context ,
20- stopAt : Context ,
21- prevValDef : Option [String ]): List [(String , Int )] = {
22- if (ctx == stopAt)
23- List ()
24- else ctx.tree match {
25- case vd @ ValDef (_, name, _, _) if prevValDef.isEmpty || (! prevValDef.get.equals(name.toString)) =>
26- (name.toString, vd.pos.line) :: contextSourceInfoChain(ctx.outer, stopAt, Some (name.toString))
27- // case app @ Apply(fun, args) if fun.symbol.isMethod =>
28- // (fun.symbol.nameString, fun.pos.line) :: contextSourceInfoChain(ctx.outer, stopAt)
29- case _ =>
30- contextSourceInfoChain(ctx.outer, stopAt, None )
19+ def contextSourceInfoChain (ctx : Context ,
20+ stopAt : Context ,
21+ prevValDef : Option [String ]): List [(String , Int )] = {
22+ if (ctx == stopAt)
23+ List ()
24+ else ctx.tree match {
25+ case vd @ ValDef (_, name, _, _) if prevValDef.isEmpty || (! prevValDef.get.equals(name.toString)) =>
26+ (name.toString, vd.pos.line) :: contextSourceInfoChain(ctx.outer, stopAt, Some (name.toString))
27+ // case app @ Apply(fun, args) if fun.symbol.isMethod =>
28+ // (fun.symbol.nameString, fun.pos.line) :: contextSourceInfoChain(ctx.outer, stopAt)
29+ case _ =>
30+ contextSourceInfoChain(ctx.outer, stopAt, None )
31+ }
32+ }
33+
34+ def contextInfoChain (ctx : Context , tree : Tree ) = ctx.tree match {
35+ case vd @ ValDef (_, name, _, _) =>
36+ // println("current context tree is ValDef "+name)
37+ contextSourceInfoChain(ctx, ctx.enclClass, None )
38+ case _ =>
39+ // println("current context tree: "+ctx.tree)
40+ val l = tree.pos match {
41+ case NoPosition => 0
42+ case _ => tree.pos.line
3143 }
44+ (null , l) :: contextSourceInfoChain(ctx.outer, ctx.outer.enclClass, None )
45+ }
46+
47+ def sourceInfoTree (chain : List [(String , Int )]): Tree = chain match {
48+ case (name, line) :: rest =>
49+ val pairTree = gen.mkTuple(List (Literal (Constant (name)), Literal (Constant (line))))
50+ Apply (Select (gen.mkAttributedRef(ListModule ), nme.apply), List (pairTree))
51+ case List () =>
52+ gen.mkNil
53+ }
54+
55+ /** Creates a tree that calls the factory method called constructor in object reflect.SourceContext */
56+ def sourceInfoFactoryCall (typer : Typer , infoTree : Tree , constructor : String , args : Tree * ): Tree =
57+ if (args contains EmptyTree ) EmptyTree
58+ else typer.typedPos(infoTree.pos.focus) {
59+ Apply (
60+ Select (gen.mkAttributedRef(SourceContextModule ), constructor),
61+ args.toList
62+ )
3263 }
3364
34- def contextInfoChain (ctx : Context , tree : Tree ) = ctx.tree match {
35- case vd @ ValDef (_, name, _, _) =>
36- // println("current context tree is ValDef "+name)
37- contextSourceInfoChain(ctx, ctx.enclClass, None )
38- case _ =>
39- // println("current context tree: "+ctx.tree)
40- val l = tree.pos match {
41- case NoPosition => 0
42- case _ => tree.pos.line
43- }
44- (null , l) :: contextSourceInfoChain(ctx.outer, ctx.outer.enclClass, None )
65+ def methodNameOf (tree : Tree ) = {
66+ tree match {
67+ case Apply (TypeApply (s, _), _) => s.symbol.name
68+ case Apply (s@ Select (_, _), _) => s.symbol.name
69+ case Apply (s@ Ident (_), _) => s.symbol.name
70+ case Apply (Apply (s, _), _) => s.symbol.name
71+ case s@ Select (_, _) => s.symbol.name
72+ case other => " "
4573 }
74+ }
4675
47- def sourceInfoTree (chain : List [(String , Int )]): Tree = chain match {
48- case (name, line) :: rest =>
49- val pairTree = gen.mkTuple(List (Literal (Constant (name)), Literal (Constant (line))))
50- Apply (Select (gen.mkAttributedRef(ListModule ), nme.apply), List (pairTree))
51- case List () =>
52- gen.mkNil
76+ def receiverOptOf (tree : Tree ) = {
77+ try {
78+ tree match {
79+ case Apply (TypeApply (Select (recv, _), _), _) => Some (recv.symbol.name)
80+ case Apply (Select (recv, _), _) => Some (recv.symbol.name)
81+ case Select (recv, _) => Some (recv.symbol.name)
82+ case _ => None
83+ }
84+ } catch {
85+ case npe : NullPointerException =>
86+ None
87+ }
88+ }
89+
90+ def sourceInfo (typer : Typer , infoContext : Context , infoTree : Tree ): SearchResult = {
91+ def srcInfo ()(implicit from : List [Symbol ] = List (), to : List [Type ] = List ()): SearchResult = {
92+ implicit def wrapResult (tree : Tree ): SearchResult =
93+ if (tree == EmptyTree ) SearchFailure else new SearchResult (tree, new TreeTypeSubstituter (from, to))
94+
95+ val methodName = methodNameOf(infoTree)
96+ val receiver = receiverOptOf(infoTree)
97+
98+ // println("context source info chain:")
99+ // println(contextInfoChain)
100+ // println("source info tree:")
101+ // println(sourceInfoTree(contextInfoChain))
102+
103+ val position = infoTree.pos.focus
104+ val fileName = if (position.isDefined) position.source.file.absolute.path
105+ else " <unknown file>"
106+ if (receiver.isEmpty)
107+ sourceInfoFactoryCall(typer, infoTree, " apply" , Literal (Constant (fileName)), Literal (Constant (methodName.toString)), sourceInfoTree(contextInfoChain(infoContext, infoTree)))
108+ else
109+ sourceInfoFactoryCall(typer, infoTree, " apply" , Literal (Constant (fileName)), Literal (Constant (methodName.toString)), Literal (Constant (receiver.get.toString)), sourceInfoTree(contextInfoChain(infoContext, infoTree)))
53110 }
54111
55- /** Creates a tree that calls the factory method called constructor in object reflect.SourceContext */
56- def sourceInfoFactoryCall (typer : Typer , infoTree : Tree , constructor : String , args : Tree * ): Tree =
112+ srcInfo()
113+ }
114+
115+ def sourceLocation (typer : Typer , infoTree : Tree ): SearchResult = {
116+ /** Creates a tree that calls the factory method called constructor in object reflect.SourceLocation */
117+ def sourceLocationFactoryCall (constructor : String , args : Tree * ): Tree =
57118 if (args contains EmptyTree ) EmptyTree
58119 else typer.typedPos(infoTree.pos.focus) {
59120 Apply (
60- Select (gen.mkAttributedRef(SourceContextModule ), constructor),
121+ Select (gen.mkAttributedRef(SourceLocationModule ), constructor),
61122 args.toList
62123 )
63124 }
64125
65- def methodNameOf (tree : Tree ) = {
66- tree match {
67- case Apply (TypeApply (s, _), _) => s.symbol.name
68- case Apply (s@ Select (_, _), _) => s.symbol.name
69- case Apply (s@ Ident (_), _) => s.symbol.name
70- case Apply (Apply (s, _), _) => s.symbol.name
71- case s@ Select (_, _) => s.symbol.name
72- case other => " "
73- }
74- }
126+ def srcLocation ()(implicit from : List [Symbol ] = List (), to : List [Type ] = List ()): SearchResult = {
127+ implicit def wrapResult (tree : Tree ): SearchResult =
128+ if (tree == EmptyTree ) SearchFailure else new SearchResult (tree, new TreeTypeSubstituter (from, to))
75129
76- def receiverOptOf (tree : Tree ) = {
77- try {
78- tree match {
79- case Apply (TypeApply (Select (recv, _), _), _) => Some (recv.symbol.name)
80- case Apply (Select (recv, _), _) => Some (recv.symbol.name)
81- case Select (recv, _) => Some (recv.symbol.name)
82- case _ => None
83- }
84- } catch {
85- case npe : NullPointerException =>
86- None
87- }
130+ val position = infoTree.pos.focus
131+ val fileName = if (position.isDefined) position.source.file.absolute.path
132+ else " <unknown file>"
133+ sourceLocationFactoryCall(" apply" , Literal (Constant (position.line)), Literal (Constant (position.point)), Literal (Constant (fileName)))
88134 }
89135
90- def sourceInfo (typer : Typer , infoContext : Context , infoTree : Tree ): SearchResult = {
91- def srcInfo ()(implicit from : List [Symbol ] = List (), to : List [Type ] = List ()): SearchResult = {
92- implicit def wrapResult (tree : Tree ): SearchResult =
93- if (tree == EmptyTree ) SearchFailure else new SearchResult (tree, new TreeTypeSubstituter (from, to))
94-
95- val methodName = methodNameOf(infoTree)
96- val receiver = receiverOptOf(infoTree)
97-
98- // println("context source info chain:")
99- // println(contextInfoChain)
100- // println("source info tree:")
101- // println(sourceInfoTree(contextInfoChain))
102-
103- val position = infoTree.pos.focus
104- val fileName = if (position.isDefined) position.source.file.absolute.path
105- else " <unknown file>"
106- if (receiver.isEmpty)
107- sourceInfoFactoryCall(typer, infoTree, " apply" , Literal (Constant (fileName)), Literal (Constant (methodName.toString)), sourceInfoTree(contextInfoChain(infoContext, infoTree)))
136+ srcLocation()
137+ }
138+
139+ /** Update search result, so that it has the correct source position.
140+ * Invoke `update` on SourceContexts for chaining.
141+ */
142+ def updatedWithSourceContext (typer : Typer , tree : Tree , pt : Type , context : Context , previous : SearchResult , updateSourceContext : Boolean ): SearchResult = pt/* .dealias*/ match {
143+ case TypeRef (_, SourceContextClass , _) if updateSourceContext =>
144+ val position = tree.pos.focus
145+ val fileName = if (position.isDefined) position.source.file.absolute.path
146+ else " <unknown file>"
147+ val methodName = methodNameOf(tree)
148+ val receiver = receiverOptOf(tree)
149+ new SearchResult (typer.typedPos(position) {
150+ // use sourceInfoFactoryCall to construct SourceContext
151+ val factoryCall = if (receiver.isEmpty)
152+ sourceInfoFactoryCall(typer, tree, " apply" , Literal (Constant (fileName)), Literal (Constant (methodName.toString)), sourceInfoTree(contextInfoChain(context, tree)))
108153 else
109- sourceInfoFactoryCall(typer, infoTree, " apply" , Literal (Constant (fileName)), Literal (Constant (methodName.toString)), Literal (Constant (receiver.get.toString)), sourceInfoTree(contextInfoChain(infoContext, infoTree)))
110- }
111-
112- srcInfo()
113- }
114-
115- def sourceLocation (typer : Typer , infoTree : Tree ): SearchResult = {
116- /** Creates a tree that calls the factory method called constructor in object reflect.SourceLocation */
117- def sourceLocationFactoryCall (constructor : String , args : Tree * ): Tree =
118- if (args contains EmptyTree ) EmptyTree
119- else typer.typedPos(infoTree.pos.focus) {
120- Apply (
121- Select (gen.mkAttributedRef(SourceLocationModule ), constructor),
122- args.toList
123- )
124- }
125-
126- def srcLocation ()(implicit from : List [Symbol ] = List (), to : List [Type ] = List ()): SearchResult = {
127- implicit def wrapResult (tree : Tree ): SearchResult =
128- if (tree == EmptyTree ) SearchFailure else new SearchResult (tree, new TreeTypeSubstituter (from, to))
129-
130- val position = infoTree.pos.focus
131- val fileName = if (position.isDefined) position.source.file.absolute.path
132- else " <unknown file>"
133- sourceLocationFactoryCall(" apply" , Literal (Constant (position.line)), Literal (Constant (position.point)), Literal (Constant (fileName)))
134- }
135-
136- srcLocation()
137- }
154+ sourceInfoFactoryCall(typer, tree, " apply" , Literal (Constant (fileName)), Literal (Constant (methodName.toString)), Literal (Constant (receiver.get.toString)), sourceInfoTree(contextInfoChain(context, tree)))
155+ Apply (Select (previous.tree, " update" ), List (factoryCall))
156+ }, previous.subst)
157+ case TypeRef (_, SourceLocationClass , _) =>
158+ val position = tree.pos.focus
159+ new SearchResult (typer.typedPos(position) {
160+ sourceLocation(typer, tree).tree
161+ }, previous.subst)
162+ case _ => previous
163+ }
138164
139165}
0 commit comments