我正在尝试将scala对象转换为js对象
object SObject {
def foo(in:String):String = s"scalajs-$in"
}
val o = ScalaObjectToJSObjectMacro(SObject) // js.Dynamical.literal(foo = (in:String) => s"scalajs-$in")
在宏中我能够获取所有对象的方法(in.tpe.decls.toList),然后对于每个方法名称,returnType,params在MethodSymbolApi中可用,但没有正文树:s
object ScalaObjectToJSObjectMacro {
def apply[T](in: T): js.Object = macro macroImpl
def macroImpl(c: blackbox.Context)(in: c.Tree): c.Tree = {
import c.universe._
val methods = in.tpe.decls.toList
.filter(s => {
s.isMethod && s.asMethod.isPublic && !s.asMethod.isConstructor
})
.map(m => {
val mt = m.asMethod
val name = mt.name
val returnType = mt.returnType
val params = mt.paramLists
val body = ??? //TODO
})
println(s"methods: ${methods}")
q"""
scala.scalajs.js.Dynamic.literal()
"""
}
}
答案 0 :(得分:0)
我能够访问方法主体的一种方法是使用以下quasiquote:
var googleearth = L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}', {
minZoom: 6,
maxZoom: 17,
attribution: 'Tiles © Esri — Source: Esri, i-cubed, USDA, USGS, AEX, GeoEye, Getmapping, Aerogrid, IGN, IGP, UPR-EGP, and the GIS User Community'
});
// Note: replacing the Tile Server to comply with Google Maps Terms.
var googleTerrain = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '© <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
});
var map = L.map("mapid", {
zoom: 10,
center: [55.7363, -6.1771],
layers: [googleearth, googleTerrain],
zoomControl: false,
attributionControl: true,
measureControl: true
});
var baseLayers = {
"Aerial Imagery": googleearth,
"googleTerrain": googleTerrain
};
L.control.layers(baseLayers, null, {
collapsed: false,
//autoZIndex: false,
}).addTo(map);
var OpenTopoMap = L.tileLayer('https://{s}.tile.opentopomap.org/{z}/{x}/{y}.png', {
zIndex: 100, // Make sure you specify a high enough value.
maxZoom: 17,
visibility: true,
attribution: 'Map data: © <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>, <a href="http://viewfinderpanoramas.org">SRTM</a> | Map style: © <a href="https://opentopomap.org">OpenTopoMap</a> (<a href="https://creativecommons.org/licenses/by-sa/3.0/">CC-BY-SA</a>)'
});
$(document).ready(function() {
$("#layercontrol2").change(function() {
if ($(this).prop("checked")) {
OpenTopoMap.addTo(map);
return;
} else {
OpenTopoMap.remove();
return;
}
});
});
方法正文包含在<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.3.1/dist/leaflet.css" integrity="sha512-Rksm5RenBEKSKFjgI3a41vrjkw4EVPlJ3+OiI65vTjIdo9brlAacEuKOiQ5OFh7cOI1bkDwLqdLw3Zg0cRJAAQ==" crossorigin="" />
<script src="https://unpkg.com/leaflet@1.3.1/dist/leaflet-src.js" integrity="sha512-IkGU/uDhB9u9F8k+2OsA6XXoowIhOuQL1NTgNZHY1nkURnqEGlDZq3GsfmdJdKFe1k1zOc6YU2K7qY+hF9AodA==" crossorigin=""></script>
<script src="https://code.jquery.com/jquery-3.3.1.js"></script>
<style></style>
</head>
<body>
<div id="mapid" style="height: 160px"></div>
<div id="layercontrol">
<input id="layercontrol2" type="checkbox" /> Topo Map
<br />
<!--input id="layercontrol3" type="checkbox" /> Satellite
<br /-->
</div>
</body>
</html>
中。请注意,通过模式匹配访问以下代码段q"..$mods def $ename[..$tparams](...$paramss): $tpeopt = $expr"
:
expr
答案 1 :(得分:0)
您可以从Symbol
获取Tree
,但反之亦然。方法正文在此方法的Tree
中不在此Tree
的{{1}}中。因此,您应该使用原始Symbol
Tree
而不使用符号in
。 tutorial中描述了遍历s
。
尝试
Tree