Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
梦境迷离
Scala Macro Tools
提交
cb3162d3
S
Scala Macro Tools
项目概览
梦境迷离
/
Scala Macro Tools
上一次同步 大约 1 年
通知
8
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
S
Scala Macro Tools
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
cb3162d3
编写于
7月 22, 2021
作者:
梦境迷离
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
[WIP] simple di
上级
7a0fd152
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
189 addition
and
0 deletion
+189
-0
src/main/scala/io/github/dreamylost/di/DiMacro.scala
src/main/scala/io/github/dreamylost/di/DiMacro.scala
+86
-0
src/test/scala/io/github/dreamylost/DiMacroTest.scala
src/test/scala/io/github/dreamylost/DiMacroTest.scala
+103
-0
未找到文件。
src/main/scala/io/github/dreamylost/di/DiMacro.scala
0 → 100644
浏览文件 @
cb3162d3
/*
* Copyright (c) 2021 jxnu-liguobin && contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package
io.github.dreamylost.di
import
scala.reflect.macros.whitebox
import
annotation.tailrec
/**
* DI Macro
*
* @author 梦境迷离
* @since 2021/7/22
* @version 1.0
*/
object
DiMacro
{
def
AutoWire
[
T
]
:
T
=
macro
AutoWireMacro
[
T
]
def
AutoWireMacro
[
T:
c.WeakTypeTag
](
c
:
whitebox.Context
)
:
c.Expr
[
T
]
=
{
import
c.universe._
// TODO: this should check if the found value uses AutoWire[]; now any value of the desired type will be returned
def
findWiredOfType
(
t
:
Type
)
:
Option
[
Name
]
=
{
@tailrec
def
doFind
(
trees
:
List
[
Tree
])
:
Option
[
Name
]
=
trees
match
{
case
Nil
=>
c
.
error
(
c
.
enclosingPosition
,
s
"Cannot find a wired value of type $t"
)
None
case
tree
::
tail
=>
tree
match
{
// TODO: subtyping
case
ValDef
(
_
,
name
,
tpt
,
_
)
if
(
tpt
.
tpe
weak_<:<
t
)
||
(
tpt
.
tpe
<:<
t
)
=>
Some
(
name
.
encodedName
)
case
DefDef
(
defDef
)
if
(
defDef
.
_5
.
tpe
weak_<:<
t
)
||
(
defDef
.
_5
.
tpe
<:<
t
)
=>
Some
(
defDef
.
_2
.
decodedName
)
case
_
=>
doFind
(
tail
)
}
}
val
ClassDef
(
_
,
_
,
_
,
Template
(
_
,
_
,
body
))
=
c
.
enclosingClass
doFind
(
body
)
}
val
tType
=
implicitly
[
c.WeakTypeTag
[
T
]]
val
tConstructorOpt
=
tType
.
tpe
.
members
.
find
(
_
.
name
.
toTermName
.
toTermName
.
toString
==
"<init>"
)
val
result
=
tConstructorOpt
match
{
case
None
=>
c
.
error
(
c
.
enclosingPosition
,
"Cannot find constructor for "
+
tType
)
reify
{
null
.
asInstanceOf
[
T
]
}
case
Some
(
tConstructor
)
=>
val
params
=
tConstructor
.
asMethod
.
paramLists
.
flatten
val
newT
=
Select
(
New
(
Ident
(
tType
.
tpe
.
typeSymbol
)),
termNames
.
CONSTRUCTOR
)
val
constructorParams
=
for
(
param
<-
params
)
yield
{
val
wireTo
=
findWiredOfType
(
param
.
typeSignature
)
// If we cannot find a value of the given type, trying a by-name match, using the same name as the constructor's parameter.
.
getOrElse
(
param
.
name
)
Ident
(
wireTo
)
}
val
newTWithParams
=
Apply
(
newT
,
constructorParams
)
c
.
info
(
c
.
enclosingPosition
,
s
"Generated code: ${c.universe.show(newTWithParams)}"
,
force
=
false
)
c
.
Expr
(
newTWithParams
)
}
result
}
}
src/test/scala/io/github/dreamylost/DiMacroTest.scala
0 → 100644
浏览文件 @
cb3162d3
/*
* Copyright (c) 2021 jxnu-liguobin && contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package
io.github.dreamylost
import
org.scalatest.flatspec.AnyFlatSpec
import
org.scalatest.matchers.should.Matchers
/**
*
* @author li.guobin@immomo.com
* @version 1.0,2021/7/22
*/
class
DiMacroTest
extends
AnyFlatSpec
with
Matchers
{
"wire1"
should
"ok"
in
{
import
io.github.dreamylost.di.DiMacro._
class
A
()
class
B
()
class
C
(
a
:
A
,
b
:
B
)
{
override
def
toString
=
s
"${super.toString}($a, $b)"
}
class
D
(
b
:
B
,
c
:
C
)
{
override
def
toString
=
s
"${super.toString}($b, $c)"
}
trait
Service
{
val
a
=
AutoWire
[
A
]
val
bbb
=
AutoWire
[
B
]
val
c
=
AutoWire
[
C
]
val
d
=
AutoWire
[
D
]
println
(
a
)
println
(
bbb
)
println
(
c
)
println
(
d
)
}
}
"wire2"
should
"ok by parameters inherit"
in
{
import
io.github.dreamylost.di.DiMacro._
class
A
()
class
B
()
extends
A
class
B1
class
C
(
b1
:
B1
,
a
:
A
)
{
override
def
toString
=
s
"${super.toString}($b1, $a)"
}
trait
Service
{
//The instance required by the constructor of the class injected by autowire must be visible within the scope of the enclosingClass.
val
b1
=
AutoWire
[
B1
]
val
b
=
AutoWire
[
B
]
val
c
=
AutoWire
[
C
]
println
(
b1
)
println
(
b
)
println
(
c
)
}
}
"wire3"
should
"ok by lazy and def"
in
{
import
io.github.dreamylost.di.DiMacro._
class
A
()
class
B
()
extends
A
class
B1
class
C
(
b1
:
B1
,
a
:
A
)
{
override
def
toString
=
s
"${super.toString}($b1, $a)"
}
trait
Service
{
lazy
val
b1
=
AutoWire
[
B1
]
def
b
:
B
=
AutoWire
[
B
]
val
c
=
AutoWire
[
C
]
println
(
b1
)
println
(
b
)
println
(
c
)
}
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录