Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
梦境迷离
Scala Macro Tools
提交
2df4ffb2
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 搜索 >>
未验证
提交
2df4ffb2
编写于
6月 13, 2022
作者:
梦境迷离
提交者:
GitHub
6月 13, 2022
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
opt (#201)
上级
08a99b34
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
57 addition
and
42 deletion
+57
-42
smt-cache/src/main/scala/org/bitlap/cache/Cache.scala
smt-cache/src/main/scala/org/bitlap/cache/Cache.scala
+4
-2
smt-common/src/main/scala/org/bitlap/common/CaseClassExtractor.scala
...src/main/scala/org/bitlap/common/CaseClassExtractor.scala
+35
-28
smt-common/src/main/scala/org/bitlap/common/CaseClassField.scala
...mon/src/main/scala/org/bitlap/common/CaseClassField.scala
+13
-5
smt-common/src/test/scala/org/bitlap/common/CaseClassExtractorTest.scala
...test/scala/org/bitlap/common/CaseClassExtractorTest.scala
+5
-7
未找到文件。
smt-cache/src/main/scala/org/bitlap/cache/Cache.scala
浏览文件 @
2df4ffb2
...
@@ -61,7 +61,9 @@ object Cache {
...
@@ -61,7 +61,9 @@ object Cache {
override
def
getTField
(
key
:
String
,
field
:
CaseClassField
)(
implicit
override
def
getTField
(
key
:
String
,
field
:
CaseClassField
)(
implicit
keyBuilder
:
CacheKeyBuilder
[
String
]
keyBuilder
:
CacheKeyBuilder
[
String
]
)
:
Future
[
Option
[
field.Field
]]
=
)
:
Future
[
Option
[
field.Field
]]
=
getT
(
key
).
map
(
opt
=>
opt
.
flatMap
(
t
=>
CaseClassExtractor
.
getFieldValueUnSafely
[
cache.Out
](
t
,
field
)))
getT
(
key
).
map
(
opt
=>
opt
.
flatMap
(
t
=>
CaseClassExtractor
.
ofValue
[
cache.Out
](
t
,
field
).
asInstanceOf
[
Option
[
field.Field
]])
)
override
def
clear
()
:
Future
[
Unit
]
=
cache
.
clear
()
override
def
clear
()
:
Future
[
Unit
]
=
cache
.
clear
()
}
}
...
@@ -91,7 +93,7 @@ object Cache {
...
@@ -91,7 +93,7 @@ object Cache {
override
def
getTField
(
key
:
String
,
field
:
CaseClassField
)(
implicit
override
def
getTField
(
key
:
String
,
field
:
CaseClassField
)(
implicit
keyBuilder
:
CacheKeyBuilder
[
String
]
keyBuilder
:
CacheKeyBuilder
[
String
]
)
:
Identity
[
Option
[
field.Field
]]
=
)
:
Identity
[
Option
[
field.Field
]]
=
getT
(
key
).
flatMap
(
t
=>
CaseClassExtractor
.
getFieldValueUnSafely
[
cache.Out
](
t
,
field
)
)
getT
(
key
).
flatMap
(
t
=>
CaseClassExtractor
.
ofValue
[
cache.Out
](
t
,
field
).
asInstanceOf
[
Option
[
field.Field
]]
)
override
def
clear
()
:
Identity
[
Unit
]
=
cache
.
clear
()
override
def
clear
()
:
Identity
[
Unit
]
=
cache
.
clear
()
}
}
...
...
smt-common/src/main/scala/org/bitlap/common/CaseClassExtractor.scala
浏览文件 @
2df4ffb2
...
@@ -35,42 +35,25 @@ import scala.util.{ Failure, Success }
...
@@ -35,42 +35,25 @@ import scala.util.{ Failure, Success }
*/
*/
object
CaseClassExtractor
{
object
CaseClassExtractor
{
def
getFieldValueUnSafely
[
T:
ru.TypeTag
](
obj
:
T
,
field
:
CaseClassField
)(
implicit
/** Using the characteristics of the product type to get the field value should force the conversion externally
classTag
:
ClassTag
[
T
]
* (safely).
)
:
Option
[
field.Field
]
=
{
*/
val
mirror
=
ru
.
runtimeMirror
(
getClass
.
getClassLoader
)
def
ofValue
[
T
<:
Product
](
t
:
T
,
field
:
CaseClassField
)
:
Option
[
Any
]
=
macro
macroImpl
[
T
]
val
fieldOption
=
scala
.
util
.
Try
(
getMethods
[
T
]
.
filter
(
_
.
name
.
toTermName
.
decodedName
.
toString
==
field
.
stringify
)
.
map
(
m
=>
mirror
.
reflect
(
obj
).
reflectField
(
m
).
get
)
.
headOption
.
map
(
_
.
asInstanceOf
[
field.Field
])
)
fieldOption
match
{
case
Success
(
value
)
=>
value
case
Failure
(
exception
)
=>
exception
.
printStackTrace
();
None
}
}
def
getMethods
[
T:
ru.TypeTag
]
:
List
[
ru.MethodSymbol
]
=
typeOf
[
T
].
members
.
collect
{
case
m
:
MethodSymbol
if
m.isCaseAccessor
=>
m
}.
toList
def
getFieldValueSafely
[
T
<:
Product
,
Field
](
t
:
T
,
name
:
String
)
:
Option
[
Field
]
=
macro
macroImpl
[
T
,
Field
]
def
macroImpl
[
T:
c.WeakTypeTag
,
Field:
c.WeakTypeTag
](
def
macroImpl
[
T:
c.WeakTypeTag
](
c
:
whitebox.Context
c
:
whitebox.Context
)(
t
:
c.Expr
[
T
],
name
:
c.Expr
[
String
])
:
c.Expr
[
Option
[
Field
]]
=
{
)(
t
:
c.Expr
[
T
],
field
:
c.Expr
[
CaseClassField
])
:
c.Expr
[
Option
[
Any
]]
=
{
import
c.universe._
import
c.universe._
val
typ
=
TypeName
(
c
.
weakTypeOf
[
Field
].
typeSymbol
.
name
.
decodedName
.
toString
)
// scalafmt: { maxColumn = 400 }
val
tree
=
val
tree
=
q
"""
q
"""
if ($t == null) None else {
if ($t == null) None else {
val idx = $t.productElementNames.indexOf($name)
val _field = $field
Option($t.productElement(idx).asInstanceOf[$typ])
_field.${TermName(CaseClassField.fieldNamesTermName)}.find(kv => kv._2 == _field.${TermName(CaseClassField.stringifyTermName)})
.map(kv => $t.productElement(kv._1))
}
}
"""
"""
exprPrintTree
[
Option
[
Field
]](
c
)(
tree
)
exprPrintTree
[
Option
[
Any
]](
c
)(
tree
)
}
}
...
@@ -83,4 +66,28 @@ object CaseClassExtractor {
...
@@ -83,4 +66,28 @@ object CaseClassExtractor {
)
)
c
.
Expr
[
Field
](
resTree
)
c
.
Expr
[
Field
](
resTree
)
}
}
/** Using scala reflect to get the field value (safely).
*/
@deprecated
def
reflectValue
[
T:
ru.TypeTag
](
obj
:
T
,
field
:
CaseClassField
)(
implicit
classTag
:
ClassTag
[
T
]
)
:
Option
[
field.Field
]
=
{
val
mirror
=
ru
.
runtimeMirror
(
getClass
.
getClassLoader
)
val
fieldOption
=
scala
.
util
.
Try
(
getMethods
[
T
]
.
filter
(
_
.
name
.
toTermName
.
decodedName
.
toString
==
field
.
stringify
)
.
map
(
m
=>
mirror
.
reflect
(
obj
).
reflectField
(
m
).
get
)
.
headOption
.
map
(
_
.
asInstanceOf
[
field.Field
])
)
fieldOption
match
{
case
Success
(
value
)
=>
value
case
Failure
(
exception
)
=>
exception
.
printStackTrace
();
None
}
}
def
getMethods
[
T:
ru.TypeTag
]
:
List
[
ru.MethodSymbol
]
=
typeOf
[
T
].
members
.
collect
{
case
m
:
MethodSymbol
if
m.isCaseAccessor
=>
m
}.
toList
}
}
smt-common/src/main/scala/org/bitlap/common/CaseClassField.scala
浏览文件 @
2df4ffb2
...
@@ -31,13 +31,18 @@ trait CaseClassField {
...
@@ -31,13 +31,18 @@ trait CaseClassField {
def
stringify
:
String
def
stringify
:
String
type
Field
type
Field
/** product index -> name, scala2.11 2.12 not `productElementNames`
*/
val
fieldIndexNames
:
Map
[
Int
,
String
]
}
}
object
CaseClassField
{
object
CaseClassField
{
final
val
classNameTermName
=
"CaseClassField"
final
val
classNameTermName
=
"CaseClassField"
final
val
stringifyTermName
=
"stringify"
final
val
stringifyTermName
=
"stringify"
final
val
fieldTermName
=
"Field"
final
val
fieldTermName
=
"Field"
final
val
fieldNamesTermName
=
"fieldIndexNames"
def
apply
[
T
<:
Product
](
field
:
T
=>
Any
)
:
CaseClassField
=
macro
selectFieldMacroImpl
[
T
]
def
apply
[
T
<:
Product
](
field
:
T
=>
Any
)
:
CaseClassField
=
macro
selectFieldMacroImpl
[
T
]
...
@@ -74,17 +79,20 @@ object CaseClassField {
...
@@ -74,17 +79,20 @@ object CaseClassField {
}
}
val
fieldNameTypeName
=
TermName
(
s
"${CaseClassField.classNameTermName}$$$fieldName"
)
val
fieldNameTypeName
=
TermName
(
s
"${CaseClassField.classNameTermName}$$$fieldName"
)
val
res
=
q
"""
val
res
=
q
"""
case object $fieldNameTypeName extends $packageName.${TypeName(CaseClassField.classNameTermName)} {
case object $fieldNameTypeName extends $packageName.${TypeName(CaseClassField.classNameTermName)} {
override def ${TermName(CaseClassField.stringifyTermName)}: String = $fieldName
override def ${TermName(CaseClassField.stringifyTermName)}: String = $fieldName
override type ${TypeName(CaseClassField.fieldTermName)} = $genericType
override type ${TypeName(CaseClassField.fieldTermName)} = $genericType
override val ${TermName(CaseClassField.fieldNamesTermName)} =
(${caseClassParams.indices.toList} zip ${caseClassParams.map(_.name.decodedName.toString)}).toMap
}
}
$fieldNameTypeName
$fieldNameTypeName
"""
"""
exprPrintTree
[
CaseClassField
](
c
)(
res
)
exprPrintTree
[
CaseClassField
](
c
)(
res
)
}
}
private
def
getCaseClassParams
[
T:
c.WeakTypeTag
](
c
:
whitebox.Context
)
:
List
[
c.Symbol
]
=
{
def
getCaseClassParams
[
T:
c.WeakTypeTag
](
c
:
whitebox.Context
)
:
List
[
c.Symbol
]
=
{
import
c.universe._
import
c.universe._
val
parameters
=
c
.
weakTypeOf
[
T
].
resultType
.
member
(
TermName
(
"<init>"
)).
typeSignature
.
paramLists
val
parameters
=
c
.
weakTypeOf
[
T
].
resultType
.
member
(
TermName
(
"<init>"
)).
typeSignature
.
paramLists
if
(
parameters
.
size
>
1
)
{
if
(
parameters
.
size
>
1
)
{
...
...
smt-common/src/test/scala/org/bitlap/common/CaseClassExtractorTest.scala
浏览文件 @
2df4ffb2
...
@@ -31,10 +31,9 @@ import org.scalatest.matchers.should.Matchers
...
@@ -31,10 +31,9 @@ import org.scalatest.matchers.should.Matchers
class
CaseClassExtractorTest
extends
AnyFlatSpec
with
Matchers
{
class
CaseClassExtractorTest
extends
AnyFlatSpec
with
Matchers
{
"CaseClassExtractorTest1"
should
"safe"
in
{
"CaseClassExtractorTest1"
should
"safe"
in
{
val
obj
=
TestEntity
(
"name"
,
"id"
,
"key"
,
Some
(
1
))
val
obj
=
TestEntity
(
"name"
,
"id"
,
"key"
,
Some
(
1
))
val
keyField
=
CaseClassField
[
TestEntity
](
_
.
key
)
val
key
=
CaseClassExtractor
.
ofValue
(
obj
,
CaseClassField
[
TestEntity
](
_
.
key
))
val
key
=
println
(
key
)
CaseClassExtractor
.
getFieldValueSafely
[
TestEntity
,
keyField.Field
](
obj
,
keyField
.
stringify
)
assert
(
key
==
Option
(
"key"
))
assert
(
key
==
Option
(
"key"
))
}
}
...
@@ -47,9 +46,8 @@ class CaseClassExtractorTest extends AnyFlatSpec with Matchers {
...
@@ -47,9 +46,8 @@ class CaseClassExtractorTest extends AnyFlatSpec with Matchers {
}
}
"CaseClassExtractorTest3"
should
"unsafe"
in
{
"CaseClassExtractorTest3"
should
"unsafe"
in
{
val
obj
=
TestEntity
(
"name"
,
"id"
,
"key"
,
Some
(
1
))
val
obj
=
TestEntity
(
"name"
,
"id"
,
"key"
,
Some
(
1
))
val
key
:
Option
[
CaseClassField
#
Field
]
=
val
key
:
Option
[
CaseClassField
#
Field
]
=
CaseClassExtractor
.
reflectValue
(
obj
,
CaseClassField
[
TestEntity
](
_
.
key
))
CaseClassExtractor
.
getFieldValueUnSafely
(
obj
,
CaseClassField
[
TestEntity
](
_
.
key
))
assert
(
key
==
Option
(
"key"
))
assert
(
key
==
Option
(
"key"
))
}
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录