Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
梦境迷离
Scala Macro Tools
提交
cc179734
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 搜索 >>
提交
cc179734
编写于
8月 01, 2021
作者:
梦境迷离
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
refactor
上级
004baeff
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
36 addition
and
30 deletion
+36
-30
src/main/scala/io/github/dreamylost/macros/AbstractMacroProcessor.scala
.../io/github/dreamylost/macros/AbstractMacroProcessor.scala
+24
-7
src/main/scala/io/github/dreamylost/macros/builderMacro.scala
...main/scala/io/github/dreamylost/macros/builderMacro.scala
+2
-2
src/main/scala/io/github/dreamylost/macros/constructorMacro.scala
.../scala/io/github/dreamylost/macros/constructorMacro.scala
+9
-17
src/main/scala/io/github/dreamylost/macros/equalsAndHashCodeMacro.scala
.../io/github/dreamylost/macros/equalsAndHashCodeMacro.scala
+1
-4
未找到文件。
src/main/scala/io/github/dreamylost/macros/AbstractMacroProcessor.scala
浏览文件 @
cc179734
...
...
@@ -176,8 +176,8 @@ abstract class AbstractMacroProcessor(val c: whitebox.Context) {
/**
* Check whether the mods of the fields has a `private[this]` or `protected[this]`, because it cannot be used out of class.
*
* @param tree
a field or method
* @return
* @param tree
Tree is a field or method?
* @return
false if mods exists private[this] or protected[this]
*/
def
isNotLocalClassMember
(
tree
:
Tree
)
:
Boolean
=
{
lazy
val
modifierNotLocal
=
(
mods
:
Modifiers
)
=>
{
...
...
@@ -246,6 +246,26 @@ abstract class AbstractMacroProcessor(val c: whitebox.Context) {
}).
map
(
_
.
asInstanceOf
[
ValDef
])
}
/**
* Extract the constructor params ValDef and flatten for currying.
*
* @param annotteeClassParams
* @return {{ Seq(ValDef) }}
*/
def
getClassConstructorValDefsFlatten
(
annotteeClassParams
:
List
[
List
[
Tree
]])
:
Seq
[
ValDef
]
=
{
annotteeClassParams
.
flatten
.
map
(
_
.
asInstanceOf
[
ValDef
])
}
/**
* Extract the constructor params ValDef not flatten.
*
* @param annotteeClassParams
* @return {{ Seq(Seq(ValDef)) }}
*/
def
getClassConstructorValDefsNotFlatten
(
annotteeClassParams
:
List
[
List
[
Tree
]])
:
Seq
[
Seq
[
ValDef
]]
=
{
annotteeClassParams
.
map
(
_
.
map
(
_
.
asInstanceOf
[
ValDef
]))
}
/**
* Extract the methods belonging to the class, contains Secondary Constructor.
*
...
...
@@ -268,9 +288,8 @@ abstract class AbstractMacroProcessor(val c: whitebox.Context) {
* @example {{ new TestClass12(i)(j)(k)(t) }}
*/
def
getConstructorWithCurrying
(
typeName
:
TypeName
,
fieldss
:
List
[
List
[
Tree
]],
isCase
:
Boolean
)
:
Tree
=
{
val
allFieldsTermName
=
fieldss
.
map
(
f
=>
f
.
map
{
case
v
:
ValDef
=>
v
.
name
.
toTermName
})
val
fieldssValDefNotFlatten
=
getClassConstructorValDefsNotFlatten
(
fieldss
)
val
allFieldsTermName
=
fieldssValDefNotFlatten
.
map
(
_
.
map
(
_
.
name
.
toTermName
))
// not currying
val
constructor
=
if
(
fieldss
.
isEmpty
||
fieldss
.
size
==
1
)
{
q
"${if (isCase) q"
$
{
typeName
.
toTermName
}(..
$
{
allFieldsTermName
.
flatten
})
" else q"
new
$typeName
(..
$
{
allFieldsTermName
.
flatten
})
"}"
...
...
@@ -280,7 +299,6 @@ abstract class AbstractMacroProcessor(val c: whitebox.Context) {
if
(
isCase
)
q
"${typeName.toTermName}(...$first)(...${allFieldsTermName.tail})"
else
q
"new $typeName(..$first)(...${allFieldsTermName.tail})"
}
c
.
info
(
c
.
enclosingPosition
,
s
"getConstructorWithCurrying constructor: $constructor, paramss: $fieldss"
,
force
=
true
)
constructor
}
...
...
@@ -303,7 +321,6 @@ abstract class AbstractMacroProcessor(val c: whitebox.Context) {
val
first
=
allFieldsTermName
.
head
q
"def apply[..$classTypeParams](..$first)(...${allFieldsTermName.tail}): $typeName[..$returnTypeParams] = ${getConstructorWithCurrying(typeName, fieldss, isCase = false)}"
}
c
.
info
(
c
.
enclosingPosition
,
s
"getApplyMethodWithCurrying constructor: $applyMethod, paramss: $fieldss"
,
force
=
true
)
applyMethod
}
...
...
src/main/scala/io/github/dreamylost/macros/builderMacro.scala
浏览文件 @
cc179734
...
...
@@ -82,14 +82,14 @@ object builderMacro {
}
override
def
modifiedDeclaration
(
classDecl
:
ClassDef
,
compDeclOpt
:
Option
[
ModuleDef
]
=
None
)
:
Any
=
{
val
(
className
,
fields
s
,
classTypeParams
)
=
classDecl
match
{
val
(
className
,
annotteeClassParam
s
,
classTypeParams
)
=
classDecl
match
{
// @see https://scala-lang.org/files/archive/spec/2.13/05-classes-and-objects.html
case
q
"$mods class $tpname[..$tparams](...$paramss) extends ..$bases { ..$body }"
=>
(
tpname
.
asInstanceOf
[
TypeName
],
paramss
.
asInstanceOf
[
List
[
List
[
Tree
]]],
tparams
.
asInstanceOf
[
List
[
Tree
]])
case
_
=>
c
.
abort
(
c
.
enclosingPosition
,
s
"${ErrorMessage.ONLY_CLASS} classDef: $classDecl"
)
}
val
builder
=
getBuilderClassAndMethod
(
className
,
fields
s
,
classTypeParams
,
isCaseClass
(
classDecl
))
val
builder
=
getBuilderClassAndMethod
(
className
,
annotteeClassParam
s
,
classTypeParams
,
isCaseClass
(
classDecl
))
val
compDecl
=
modifiedCompanion
(
compDeclOpt
,
builder
,
className
)
// Return both the class and companion object declarations
c
.
Expr
(
...
...
src/main/scala/io/github/dreamylost/macros/constructorMacro.scala
浏览文件 @
cc179734
...
...
@@ -54,14 +54,13 @@ object constructorMacro {
* Extract the internal fields of members belonging to the class, but not in primary constructor and only `var`.
*/
private
def
getMemberVarDefTermNameWithType
(
annotteeClassDefinitions
:
Seq
[
Tree
])
:
Seq
[
Tree
]
=
{
getMutableValDefAndExcludeFields
(
annotteeClassDefinitions
).
map
{
case
v
:
ValDef
if
v.mods.hasFlag
(
Flag.MUTABLE
)
=>
if
(
v
.
tpt
.
isEmpty
)
{
// val i = 1, tpt is `<type ?>`
// TODO getClass RETURN a java type, maybe we can try use class reflect to get the fields type name.
q
"${v.name}: ${TypeName(toScalaType(evalTree(v.rhs).getClass.getTypeName))}"
}
else
{
q
"${v.name}: ${v.tpt}"
}
getMutableValDefAndExcludeFields
(
annotteeClassDefinitions
).
map
{
v
=>
if
(
v
.
tpt
.
isEmpty
)
{
// val i = 1, tpt is `<type ?>`
// TODO getClass RETURN a java type, maybe we can try use class reflect to get the fields type name.
q
"${v.name}: ${TypeName(toScalaType(evalTree(v.rhs).getClass.getTypeName))}"
}
else
{
q
"${v.name}: ${v.tpt}"
}
}
}
...
...
@@ -75,15 +74,8 @@ object constructorMacro {
c
.
abort
(
c
.
enclosingPosition
,
s
"${ErrorMessage.ONLY_CLASS} and the internal fields (declare as 'var') should not be Empty."
)
}
// Extract the internal fields of members belonging to the class, but not in primary constructor.
val
annotteeClassFieldNames
=
getMutableValDefAndExcludeFields
(
annotteeClassDefinitions
).
map
{
case
v
:
ValDef
if
v.mods.hasFlag
(
Flag.MUTABLE
)
=>
v
.
name
}
// Extract the field of the primary constructor.
val
allFieldsTermName
=
annotteeClassParams
.
map
(
f
=>
f
.
map
{
case
v
:
ValDef
=>
v
.
name
.
toTermName
})
val
annotteeClassFieldNames
=
getMutableValDefAndExcludeFields
(
annotteeClassDefinitions
).
map
(
_
.
name
)
val
allFieldsTermName
=
getClassConstructorValDefsNotFlatten
(
annotteeClassParams
).
map
(
_
.
map
(
_
.
name
.
toTermName
))
// Extract the field of the primary constructor.
val
classParamsNameWithType
=
getConstructorParamsNameWithType
(
annotteeClassParams
.
flatten
)
val
applyMethod
=
if
(
annotteeClassParams
.
isEmpty
||
annotteeClassParams
.
size
==
1
)
{
...
...
src/main/scala/io/github/dreamylost/macros/equalsAndHashCodeMacro.scala
浏览文件 @
cc179734
...
...
@@ -127,10 +127,7 @@ object equalsAndHashCodeMacro {
(
tpname
.
asInstanceOf
[
TypeName
],
paramss
.
asInstanceOf
[
List
[
List
[
Tree
]]],
stats
.
asInstanceOf
[
Seq
[
Tree
]],
parents
.
asInstanceOf
[
Seq
[
Tree
]])
case
_
=>
c
.
abort
(
c
.
enclosingPosition
,
s
"${ErrorMessage.ONLY_CLASS} classDef: $classDecl"
)
}
val
ctorFieldNames
=
annotteeClassParams
.
flatten
.
filter
(
cf
=>
isNotLocalClassMember
(
cf
))
val
allFieldsTermName
=
ctorFieldNames
.
map
{
case
v
:
ValDef
=>
v
.
name
.
toTermName
}
val
allFieldsTermName
=
getClassConstructorValDefsFlatten
(
annotteeClassParams
).
filter
(
cf
=>
isNotLocalClassMember
(
cf
)).
map
(
_
.
name
.
toTermName
)
val
allTernNames
=
allFieldsTermName
++
getInternalFieldsTermNameExcludeLocal
(
annotteeClassDefinitions
)
val
hash
=
getHashcodeMethod
(
allTernNames
,
superClasses
)
val
equals
=
getEqualsMethod
(
className
,
allTernNames
,
superClasses
,
annotteeClassDefinitions
)
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录