Skip to content

Commit 1ef4ad2

Browse files
committed
Move code for updating search result for SourceLocation/SourceContext into SourceContextUtils
1 parent 69f8e42 commit 1ef4ad2

File tree

2 files changed

+128
-124
lines changed

2 files changed

+128
-124
lines changed

src/compiler/scala/tools/nsc/typechecker/Implicits.scala

Lines changed: 1 addition & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1277,29 +1277,7 @@ trait Implicits extends SourceContextUtils {
12771277
if (result == SearchFailure && settings.debug.value)
12781278
log("no implicits found for "+pt+" "+pt.typeSymbol.info.baseClasses+" "+implicitsOfExpectedType)
12791279

1280-
val updatedRes = pt/*.dealias*/ match {
1281-
case TypeRef(_, SourceContextClass, _) if updateSourceContext =>
1282-
val position = tree.pos.focus
1283-
val fileName = if (position.isDefined) position.source.file.absolute.path
1284-
else "<unknown file>"
1285-
val methodName = methodNameOf(tree)
1286-
val receiver = receiverOptOf(tree)
1287-
new SearchResult(typedPos(position) {
1288-
// use sourceInfoFactoryCall to construct SourceContext
1289-
val factoryCall = if (receiver.isEmpty)
1290-
sourceInfoFactoryCall(this, tree, "apply", Literal(Constant(fileName)), Literal(Constant(methodName.toString)), sourceInfoTree(contextInfoChain(context0, tree)))
1291-
else
1292-
sourceInfoFactoryCall(this, tree, "apply", Literal(Constant(fileName)), Literal(Constant(methodName.toString)), Literal(Constant(receiver.get.toString)), sourceInfoTree(contextInfoChain(context0, tree)))
1293-
Apply(Select(result.tree, "update"), List(factoryCall))
1294-
}, result.subst)
1295-
case TypeRef(_, SourceLocationClass, _) =>
1296-
val position = tree.pos.focus
1297-
new SearchResult(typedPos(position) {
1298-
sourceLocation(this, tree).tree
1299-
}, result.subst)
1300-
case _ => result
1301-
}
1302-
updatedRes
1280+
updatedWithSourceContext(this, tree, pt, context0, result, updateSourceContext)
13031281
}
13041282

13051283
def allImplicits: List[SearchResult] = {

src/compiler/scala/tools/nsc/typechecker/SourceContextUtils.scala

Lines changed: 127 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)