From cc2056e901f9e7e6f67fbb6f401e2f391ec03416 Mon Sep 17 00:00:00 2001 From: Kartikaya Gupta Date: Mon, 6 Mar 2017 18:46:30 -0500 Subject: [PATCH] Bug 1343019 - Update webrender to cset 178a65d098afcda7de0298d80d423bc80c6426ba. r=jrmuizel In addition to updating webrender and the third-party deps, this includes: - Marking some more reftests as passing with the new version of webrender. - Updating webrender bindings code to go with changes to push_stacking_context. - Passing the window dimensions to the Renderer::new function. MozReview-Commit-ID: 6dRHvAmIQ40 --HG-- rename : third_party/rust/servo-dwrote/.gitignore => third_party/rust/dwrote/.gitignore rename : third_party/rust/servo-dwrote/README.md => third_party/rust/dwrote/README.md rename : third_party/rust/servo-dwrote/src/bitmap_render_target.rs => third_party/rust/dwrote/src/bitmap_render_target.rs rename : third_party/rust/servo-dwrote/src/com_helpers.rs => third_party/rust/dwrote/src/com_helpers.rs rename : third_party/rust/servo-dwrote/src/comptr.rs => third_party/rust/dwrote/src/comptr.rs rename : third_party/rust/servo-dwrote/src/font.rs => third_party/rust/dwrote/src/font.rs rename : third_party/rust/servo-dwrote/src/font_collection.rs => third_party/rust/dwrote/src/font_collection.rs rename : third_party/rust/servo-dwrote/src/font_face.rs => third_party/rust/dwrote/src/font_face.rs rename : third_party/rust/servo-dwrote/src/font_family.rs => third_party/rust/dwrote/src/font_family.rs rename : third_party/rust/servo-dwrote/src/font_file.rs => third_party/rust/dwrote/src/font_file.rs rename : third_party/rust/servo-dwrote/src/font_file_loader_impl.rs => third_party/rust/dwrote/src/font_file_loader_impl.rs rename : third_party/rust/servo-dwrote/src/gdi_interop.rs => third_party/rust/dwrote/src/gdi_interop.rs rename : third_party/rust/servo-dwrote/src/glyph_run_analysis.rs => third_party/rust/dwrote/src/glyph_run_analysis.rs rename : third_party/rust/servo-dwrote/src/helpers.rs => third_party/rust/dwrote/src/helpers.rs rename : third_party/rust/servo-dwrote/src/rendering_params.rs => third_party/rust/dwrote/src/rendering_params.rs rename : third_party/rust/servo-dwrote/src/test.rs => third_party/rust/dwrote/src/test.rs rename : third_party/rust/servo-dwrote/src/types.rs => third_party/rust/dwrote/src/types.rs --- gfx/doc/README.webrender | 2 +- gfx/layers/ipc/CompositorBridgeChild.cpp | 5 +- gfx/layers/ipc/CompositorBridgeChild.h | 4 +- gfx/layers/ipc/CompositorBridgeParent.cpp | 4 +- gfx/layers/ipc/CompositorBridgeParent.h | 1 + .../CrossProcessCompositorBridgeParent.cpp | 1 + .../ipc/CrossProcessCompositorBridgeParent.h | 1 + gfx/layers/ipc/PCompositorBridge.ipdl | 3 +- gfx/layers/wr/WebRenderLayerManager.cpp | 3 +- gfx/webrender/Cargo.toml | 12 +- gfx/webrender/res/ps_composite.fs.glsl | 54 +- gfx/webrender/res/ps_composite.vs.glsl | 4 +- gfx/webrender/src/clip_scroll_node.rs | 119 +- gfx/webrender/src/clip_scroll_tree.rs | 64 +- gfx/webrender/src/device.rs | 24 + gfx/webrender/src/frame.rs | 216 ++- gfx/webrender/src/frame_builder.rs | 320 ++-- gfx/webrender/src/internal_types.rs | 19 +- gfx/webrender/src/platform/macos/font.rs | 12 + gfx/webrender/src/platform/unix/font.rs | 10 + gfx/webrender/src/platform/windows/font.rs | 45 +- gfx/webrender/src/record.rs | 1 + gfx/webrender/src/render_backend.rs | 34 +- gfx/webrender/src/render_task.rs | 3 + gfx/webrender/src/renderer.rs | 58 +- gfx/webrender/src/resource_cache.rs | 26 + gfx/webrender/src/scene.rs | 9 +- gfx/webrender/src/tiling.rs | 95 +- gfx/webrender_bindings/Cargo.toml | 5 +- gfx/webrender_bindings/WebRenderAPI.cpp | 13 +- gfx/webrender_bindings/WebRenderAPI.h | 3 +- gfx/webrender_bindings/src/bindings.rs | 13 +- gfx/webrender_bindings/webrender_ffi.h | 2 + gfx/webrender_traits/Cargo.toml | 14 +- gfx/webrender_traits/build.rs | 46 - gfx/webrender_traits/src/api.rs | 22 +- gfx/webrender_traits/src/display_list.rs | 38 +- gfx/webrender_traits/src/lib.rs | 6 - gfx/webrender_traits/src/stacking_context.rs | 4 +- gfx/webrender_traits/src/types.rs | 26 +- layout/reftests/bugs/reftest.list | 2 +- layout/reftests/css-blending/reftest.list | 4 +- layout/reftests/svg/reftest.list | 2 +- third_party/rust/dwrote/.cargo-checksum.json | 1 + .../rust/{serde_codegen => dwrote}/.cargo-ok | 0 .../rust/{servo-dwrote => dwrote}/.gitignore | 0 third_party/rust/dwrote/Cargo.toml | 19 + .../rust/{servo-dwrote => dwrote}/README.md | 0 third_party/rust/dwrote/appveyor.yml | 13 + .../src/bitmap_render_target.rs | 0 .../src/com_helpers.rs | 0 .../{servo-dwrote => dwrote}/src/comptr.rs | 0 .../rust/{servo-dwrote => dwrote}/src/font.rs | 0 .../src/font_collection.rs | 0 .../{servo-dwrote => dwrote}/src/font_face.rs | 0 .../src/font_family.rs | 0 .../{servo-dwrote => dwrote}/src/font_file.rs | 0 .../src/font_file_loader_impl.rs | 0 .../src/gdi_interop.rs | 0 .../src/glyph_run_analysis.rs | 0 .../{servo-dwrote => dwrote}/src/helpers.rs | 0 .../rust/{servo-dwrote => dwrote}/src/lib.rs | 5 - .../src/rendering_params.rs | 0 .../rust/{servo-dwrote => dwrote}/src/test.rs | 0 .../{servo-dwrote => dwrote}/src/types.rs | 0 .../rust/serde_codegen/.cargo-checksum.json | 1 - third_party/rust/serde_codegen/Cargo.toml | 32 - third_party/rust/serde_codegen/src/bound.rs | 121 -- third_party/rust/serde_codegen/src/de.rs | 1050 ---------- third_party/rust/serde_codegen/src/lib.rs | 171 -- third_party/rust/serde_codegen/src/ser.rs | 570 ------ .../.cargo-checksum.json | 2 +- .../rust/serde_codegen_internals/Cargo.toml | 14 +- .../serde_codegen_internals/LICENSE-APACHE | 201 ++ .../rust/serde_codegen_internals/LICENSE-MIT | 25 + .../rust/serde_codegen_internals/README.md | 71 + .../rust/serde_codegen_internals/src/ast.rs | 42 +- .../rust/serde_codegen_internals/src/attr.rs | 348 +++- .../rust/serde_codegen_internals/src/case.rs | 115 ++ .../rust/serde_codegen_internals/src/ctxt.rs | 4 +- .../rust/serde_codegen_internals/src/lib.rs | 5 +- .../rust/serde_derive/.cargo-checksum.json | 1 + .../{servo-dwrote => serde_derive}/.cargo-ok | 0 third_party/rust/serde_derive/Cargo.toml | 27 + third_party/rust/serde_derive/LICENSE-APACHE | 201 ++ third_party/rust/serde_derive/LICENSE-MIT | 25 + third_party/rust/serde_derive/README.md | 71 + third_party/rust/serde_derive/src/bound.rs | 228 +++ third_party/rust/serde_derive/src/de.rs | 1404 ++++++++++++++ third_party/rust/serde_derive/src/fragment.rs | 67 + third_party/rust/serde_derive/src/lib.rs | 40 + third_party/rust/serde_derive/src/ser.rs | 782 ++++++++ .../rust/servo-dwrote/.cargo-checksum.json | 1 - third_party/rust/servo-dwrote/Cargo.toml | 30 - third_party/rust/servo-dwrote/build.rs | 46 - .../rust/syn-0.10.8/.cargo-checksum.json | 1 - third_party/rust/syn-0.10.8/.cargo-ok | 0 third_party/rust/syn-0.10.8/Cargo.toml | 32 - .../rust/syn-0.10.8/src/aster/generics.rs | 233 --- .../rust/syn-0.10.8/src/aster/ident.rs | 39 - .../rust/syn-0.10.8/src/aster/invoke.rs | 16 - .../rust/syn-0.10.8/src/aster/lifetime.rs | 103 - third_party/rust/syn-0.10.8/src/aster/mod.rs | 33 - third_party/rust/syn-0.10.8/src/aster/path.rs | 331 ---- .../rust/syn-0.10.8/src/aster/qpath.rs | 146 -- third_party/rust/syn-0.10.8/src/aster/ty.rs | 578 ------ .../rust/syn-0.10.8/src/aster/ty_param.rs | 262 --- .../syn-0.10.8/src/aster/where_predicate.rs | 259 --- third_party/rust/syn-0.10.8/src/attr.rs | 293 --- third_party/rust/syn-0.10.8/src/constant.rs | 167 -- third_party/rust/syn-0.10.8/src/data.rs | 245 --- third_party/rust/syn-0.10.8/src/escape.rs | 292 --- third_party/rust/syn-0.10.8/src/expr.rs | 1701 ----------------- third_party/rust/syn-0.10.8/src/generics.rs | 446 ----- third_party/rust/syn-0.10.8/src/helper.rs | 137 -- third_party/rust/syn-0.10.8/src/ident.rs | 129 -- third_party/rust/syn-0.10.8/src/item.rs | 1477 -------------- third_party/rust/syn-0.10.8/src/krate.rs | 57 - third_party/rust/syn-0.10.8/src/lib.rs | 170 -- third_party/rust/syn-0.10.8/src/lit.rs | 455 ----- third_party/rust/syn-0.10.8/src/mac.rs | 429 ----- .../rust/syn-0.10.8/src/macro_input.rs | 110 -- third_party/rust/syn-0.10.8/src/nom.rs | 505 ----- third_party/rust/syn-0.10.8/src/op.rs | 192 -- third_party/rust/syn-0.10.8/src/registry.rs | 392 ---- third_party/rust/syn-0.10.8/src/space.rs | 99 - third_party/rust/syn-0.10.8/src/ty.rs | 826 -------- third_party/rust/syn-0.10.8/src/visit.rs | 295 --- toolkit/library/gtest/rust/Cargo.lock | 78 +- toolkit/library/rust/Cargo.lock | 78 +- 130 files changed, 4556 insertions(+), 13132 deletions(-) delete mode 100644 gfx/webrender_traits/build.rs create mode 100644 third_party/rust/dwrote/.cargo-checksum.json rename third_party/rust/{serde_codegen => dwrote}/.cargo-ok (100%) rename third_party/rust/{servo-dwrote => dwrote}/.gitignore (100%) create mode 100644 third_party/rust/dwrote/Cargo.toml rename third_party/rust/{servo-dwrote => dwrote}/README.md (100%) create mode 100644 third_party/rust/dwrote/appveyor.yml rename third_party/rust/{servo-dwrote => dwrote}/src/bitmap_render_target.rs (100%) rename third_party/rust/{servo-dwrote => dwrote}/src/com_helpers.rs (100%) rename third_party/rust/{servo-dwrote => dwrote}/src/comptr.rs (100%) rename third_party/rust/{servo-dwrote => dwrote}/src/font.rs (100%) rename third_party/rust/{servo-dwrote => dwrote}/src/font_collection.rs (100%) rename third_party/rust/{servo-dwrote => dwrote}/src/font_face.rs (100%) rename third_party/rust/{servo-dwrote => dwrote}/src/font_family.rs (100%) rename third_party/rust/{servo-dwrote => dwrote}/src/font_file.rs (100%) rename third_party/rust/{servo-dwrote => dwrote}/src/font_file_loader_impl.rs (100%) rename third_party/rust/{servo-dwrote => dwrote}/src/gdi_interop.rs (100%) rename third_party/rust/{servo-dwrote => dwrote}/src/glyph_run_analysis.rs (100%) rename third_party/rust/{servo-dwrote => dwrote}/src/helpers.rs (100%) rename third_party/rust/{servo-dwrote => dwrote}/src/lib.rs (97%) rename third_party/rust/{servo-dwrote => dwrote}/src/rendering_params.rs (100%) rename third_party/rust/{servo-dwrote => dwrote}/src/test.rs (100%) rename third_party/rust/{servo-dwrote => dwrote}/src/types.rs (100%) delete mode 100644 third_party/rust/serde_codegen/.cargo-checksum.json delete mode 100644 third_party/rust/serde_codegen/Cargo.toml delete mode 100644 third_party/rust/serde_codegen/src/bound.rs delete mode 100644 third_party/rust/serde_codegen/src/de.rs delete mode 100644 third_party/rust/serde_codegen/src/lib.rs delete mode 100644 third_party/rust/serde_codegen/src/ser.rs create mode 100644 third_party/rust/serde_codegen_internals/LICENSE-APACHE create mode 100644 third_party/rust/serde_codegen_internals/LICENSE-MIT create mode 100644 third_party/rust/serde_codegen_internals/README.md create mode 100644 third_party/rust/serde_codegen_internals/src/case.rs create mode 100644 third_party/rust/serde_derive/.cargo-checksum.json rename third_party/rust/{servo-dwrote => serde_derive}/.cargo-ok (100%) create mode 100644 third_party/rust/serde_derive/Cargo.toml create mode 100644 third_party/rust/serde_derive/LICENSE-APACHE create mode 100644 third_party/rust/serde_derive/LICENSE-MIT create mode 100644 third_party/rust/serde_derive/README.md create mode 100644 third_party/rust/serde_derive/src/bound.rs create mode 100644 third_party/rust/serde_derive/src/de.rs create mode 100644 third_party/rust/serde_derive/src/fragment.rs create mode 100644 third_party/rust/serde_derive/src/lib.rs create mode 100644 third_party/rust/serde_derive/src/ser.rs delete mode 100644 third_party/rust/servo-dwrote/.cargo-checksum.json delete mode 100644 third_party/rust/servo-dwrote/Cargo.toml delete mode 100644 third_party/rust/servo-dwrote/build.rs delete mode 100644 third_party/rust/syn-0.10.8/.cargo-checksum.json delete mode 100644 third_party/rust/syn-0.10.8/.cargo-ok delete mode 100644 third_party/rust/syn-0.10.8/Cargo.toml delete mode 100644 third_party/rust/syn-0.10.8/src/aster/generics.rs delete mode 100644 third_party/rust/syn-0.10.8/src/aster/ident.rs delete mode 100644 third_party/rust/syn-0.10.8/src/aster/invoke.rs delete mode 100644 third_party/rust/syn-0.10.8/src/aster/lifetime.rs delete mode 100644 third_party/rust/syn-0.10.8/src/aster/mod.rs delete mode 100644 third_party/rust/syn-0.10.8/src/aster/path.rs delete mode 100644 third_party/rust/syn-0.10.8/src/aster/qpath.rs delete mode 100644 third_party/rust/syn-0.10.8/src/aster/ty.rs delete mode 100644 third_party/rust/syn-0.10.8/src/aster/ty_param.rs delete mode 100644 third_party/rust/syn-0.10.8/src/aster/where_predicate.rs delete mode 100644 third_party/rust/syn-0.10.8/src/attr.rs delete mode 100644 third_party/rust/syn-0.10.8/src/constant.rs delete mode 100644 third_party/rust/syn-0.10.8/src/data.rs delete mode 100644 third_party/rust/syn-0.10.8/src/escape.rs delete mode 100644 third_party/rust/syn-0.10.8/src/expr.rs delete mode 100644 third_party/rust/syn-0.10.8/src/generics.rs delete mode 100644 third_party/rust/syn-0.10.8/src/helper.rs delete mode 100644 third_party/rust/syn-0.10.8/src/ident.rs delete mode 100644 third_party/rust/syn-0.10.8/src/item.rs delete mode 100644 third_party/rust/syn-0.10.8/src/krate.rs delete mode 100644 third_party/rust/syn-0.10.8/src/lib.rs delete mode 100644 third_party/rust/syn-0.10.8/src/lit.rs delete mode 100644 third_party/rust/syn-0.10.8/src/mac.rs delete mode 100644 third_party/rust/syn-0.10.8/src/macro_input.rs delete mode 100644 third_party/rust/syn-0.10.8/src/nom.rs delete mode 100644 third_party/rust/syn-0.10.8/src/op.rs delete mode 100644 third_party/rust/syn-0.10.8/src/registry.rs delete mode 100644 third_party/rust/syn-0.10.8/src/space.rs delete mode 100644 third_party/rust/syn-0.10.8/src/ty.rs delete mode 100644 third_party/rust/syn-0.10.8/src/visit.rs diff --git a/gfx/doc/README.webrender b/gfx/doc/README.webrender index 5d8977d60891..53bbf1513807 100644 --- a/gfx/doc/README.webrender +++ b/gfx/doc/README.webrender @@ -79,4 +79,4 @@ to make sure that mozjs_sys also has its Cargo.lock file updated if needed, henc the need to run the cargo update command in js/src as well. Hopefully this will be resolved soon. -Latest Commit: 501e3d79c8a3019762bd8bd2d00eecf7811a84de +Latest Commit: 178a65d098afcda7de0298d80d423bc80c6426ba diff --git a/gfx/layers/ipc/CompositorBridgeChild.cpp b/gfx/layers/ipc/CompositorBridgeChild.cpp index 6424428024e4..b9c393f343cc 100644 --- a/gfx/layers/ipc/CompositorBridgeChild.cpp +++ b/gfx/layers/ipc/CompositorBridgeChild.cpp @@ -1130,7 +1130,10 @@ CompositorBridgeChild::HandleFatalError(const char* aName, const char* aMsg) con } PWebRenderBridgeChild* -CompositorBridgeChild::AllocPWebRenderBridgeChild(const wr::PipelineId& aPipelineId, TextureFactoryIdentifier*, uint32_t *aIdNamespace) +CompositorBridgeChild::AllocPWebRenderBridgeChild(const wr::PipelineId& aPipelineId, + const LayoutDeviceIntSize&, + TextureFactoryIdentifier*, + uint32_t *aIdNamespace) { WebRenderBridgeChild* child = new WebRenderBridgeChild(aPipelineId); child->AddIPDLReference(); diff --git a/gfx/layers/ipc/CompositorBridgeChild.h b/gfx/layers/ipc/CompositorBridgeChild.h index bf3a05820cbf..7ed8b4547c82 100644 --- a/gfx/layers/ipc/CompositorBridgeChild.h +++ b/gfx/layers/ipc/CompositorBridgeChild.h @@ -223,7 +223,9 @@ public: void WillEndTransaction(); - PWebRenderBridgeChild* AllocPWebRenderBridgeChild(const wr::PipelineId& aPipelineId, TextureFactoryIdentifier*, + PWebRenderBridgeChild* AllocPWebRenderBridgeChild(const wr::PipelineId& aPipelineId, + const LayoutDeviceIntSize&, + TextureFactoryIdentifier*, uint32_t*) override; bool DeallocPWebRenderBridgeChild(PWebRenderBridgeChild* aActor) override; diff --git a/gfx/layers/ipc/CompositorBridgeParent.cpp b/gfx/layers/ipc/CompositorBridgeParent.cpp index 804e0e24737e..1e6d0bac3903 100644 --- a/gfx/layers/ipc/CompositorBridgeParent.cpp +++ b/gfx/layers/ipc/CompositorBridgeParent.cpp @@ -1572,6 +1572,7 @@ CompositorBridgeParent::RecvAdoptChild(const uint64_t& child) PWebRenderBridgeParent* CompositorBridgeParent::AllocPWebRenderBridgeParent(const wr::PipelineId& aPipelineId, + const LayoutDeviceIntSize& aSize, TextureFactoryIdentifier* aTextureFactoryIdentifier, uint32_t* aIdNamespace) { @@ -1588,7 +1589,8 @@ CompositorBridgeParent::AllocPWebRenderBridgeParent(const wr::PipelineId& aPipel MOZ_ASSERT(mWidget); RefPtr widget = mWidget; - RefPtr api = wr::WebRenderAPI::Create(gfxPrefs::WebRenderProfilerEnabled(), this, Move(widget)); + RefPtr api = wr::WebRenderAPI::Create( + gfxPrefs::WebRenderProfilerEnabled(), this, Move(widget), aSize); RefPtr holder = new WebRenderCompositableHolder(); MOZ_ASSERT(api); // TODO have a fallback api->SetRootPipeline(aPipelineId); diff --git a/gfx/layers/ipc/CompositorBridgeParent.h b/gfx/layers/ipc/CompositorBridgeParent.h index c6595d020e6d..7dbf2d819dfd 100644 --- a/gfx/layers/ipc/CompositorBridgeParent.h +++ b/gfx/layers/ipc/CompositorBridgeParent.h @@ -452,6 +452,7 @@ public: } PWebRenderBridgeParent* AllocPWebRenderBridgeParent(const wr::PipelineId& aPipelineId, + const LayoutDeviceIntSize& aSize, TextureFactoryIdentifier* aTextureFactoryIdentifier, uint32_t* aIdNamespace) override; bool DeallocPWebRenderBridgeParent(PWebRenderBridgeParent* aActor) override; diff --git a/gfx/layers/ipc/CrossProcessCompositorBridgeParent.cpp b/gfx/layers/ipc/CrossProcessCompositorBridgeParent.cpp index ae91468ae656..0d856e2c479b 100644 --- a/gfx/layers/ipc/CrossProcessCompositorBridgeParent.cpp +++ b/gfx/layers/ipc/CrossProcessCompositorBridgeParent.cpp @@ -198,6 +198,7 @@ CrossProcessCompositorBridgeParent::DeallocPAPZParent(PAPZParent* aActor) PWebRenderBridgeParent* CrossProcessCompositorBridgeParent::AllocPWebRenderBridgeParent(const wr::PipelineId& aPipelineId, + const LayoutDeviceIntSize& aSize, TextureFactoryIdentifier* aTextureFactoryIdentifier, uint32_t *aIdNamespace) { diff --git a/gfx/layers/ipc/CrossProcessCompositorBridgeParent.h b/gfx/layers/ipc/CrossProcessCompositorBridgeParent.h index b5a3a0459e3d..78e5bf22f203 100644 --- a/gfx/layers/ipc/CrossProcessCompositorBridgeParent.h +++ b/gfx/layers/ipc/CrossProcessCompositorBridgeParent.h @@ -152,6 +152,7 @@ public: virtual void UpdatePaintTime(LayerTransactionParent* aLayerTree, const TimeDuration& aPaintTime) override; PWebRenderBridgeParent* AllocPWebRenderBridgeParent(const wr::PipelineId& aPipelineId, + const LayoutDeviceIntSize& aSize, TextureFactoryIdentifier* aTextureFactoryIdentifier, uint32_t* aIdNamespace) override; bool DeallocPWebRenderBridgeParent(PWebRenderBridgeParent* aActor) override; diff --git a/gfx/layers/ipc/PCompositorBridge.ipdl b/gfx/layers/ipc/PCompositorBridge.ipdl index 51524eb4e3d6..440ca9e8a012 100644 --- a/gfx/layers/ipc/PCompositorBridge.ipdl +++ b/gfx/layers/ipc/PCompositorBridge.ipdl @@ -30,6 +30,7 @@ using mozilla::ipc::SharedMemoryBasic::Handle from "mozilla/ipc/SharedMemoryBasi using mozilla::CSSIntRegion from "Units.h"; using mozilla::LayoutDeviceIntPoint from "Units.h"; using mozilla::LayoutDeviceIntRegion from "Units.h"; +using mozilla::LayoutDeviceIntSize from "Units.h"; using class mozilla::TimeStamp from "mozilla/TimeStamp.h"; using class mozilla::layers::FrameUniformityData from "mozilla/layers/FrameUniformityData.h"; using mozilla::layers::TextureFlags from "mozilla/layers/CompositorTypes.h"; @@ -242,7 +243,7 @@ parent: sync SyncWithCompositor(); // The pipelineId is the same as the layersId - sync PWebRenderBridge(PipelineId pipelineId) + sync PWebRenderBridge(PipelineId pipelineId, LayoutDeviceIntSize aSize) returns (TextureFactoryIdentifier textureFactoryIdentifier, uint32_t idNamespace); //XXX: use the WrIdNamespace type child: diff --git a/gfx/layers/wr/WebRenderLayerManager.cpp b/gfx/layers/wr/WebRenderLayerManager.cpp index a19dc8c14f5c..309139358830 100644 --- a/gfx/layers/wr/WebRenderLayerManager.cpp +++ b/gfx/layers/wr/WebRenderLayerManager.cpp @@ -218,14 +218,15 @@ WebRenderLayerManager::Initialize(PCompositorBridgeChild* aCBChild, MOZ_ASSERT(mWrChild == nullptr); MOZ_ASSERT(aTextureFactoryIdentifier); + LayoutDeviceIntSize size = mWidget->GetClientSize(); TextureFactoryIdentifier textureFactoryIdentifier; uint32_t id_namespace; PWebRenderBridgeChild* bridge = aCBChild->SendPWebRenderBridgeConstructor(aLayersId, + size, &textureFactoryIdentifier, &id_namespace); MOZ_ASSERT(bridge); mWrChild = static_cast(bridge); - LayoutDeviceIntSize size = mWidget->GetClientSize(); WrBridge()->SendCreate(size.ToUnknownSize()); WrBridge()->IdentifyTextureHost(textureFactoryIdentifier); WrBridge()->SetNamespace(id_namespace); diff --git a/gfx/webrender/Cargo.toml b/gfx/webrender/Cargo.toml index 85257576eb8a..e82b02e8928c 100644 --- a/gfx/webrender/Cargo.toml +++ b/gfx/webrender/Cargo.toml @@ -1,16 +1,14 @@ [package] name = "webrender" -version = "0.19.0" +version = "0.22.1" authors = ["Glenn Watson "] license = "MPL-2.0" repository = "https://github.com/servo/webrender" build = "build.rs" [features] -default = ["codegen", "freetype-lib"] -codegen = ["webrender_traits/codegen"] +default = ["freetype-lib"] freetype-lib = ["freetype/servo-freetype-sys"] -serde_derive = ["webrender_traits/serde_derive"] profiler = ["thread_profiler/thread_profiler"] [dependencies] @@ -19,7 +17,7 @@ bincode = "1.0.0-alpha2" bit-set = "0.4" byteorder = "1.0" euclid = "0.11" -fnv="1.0" +fnv = "1.0" gleam = "0.2.30" lazy_static = "0.2" log = "0.3" @@ -27,7 +25,7 @@ num-traits = "0.1.32" offscreen_gl_context = {version = "0.6", features = ["serde", "osmesa"]} time = "0.1" threadpool = "1.3.2" -webrender_traits = {path = "../webrender_traits", default-features = false} +webrender_traits = {path = "../webrender_traits"} bitflags = "0.7" gamma-lut = "0.1" thread_profiler = "0.1.1" @@ -39,7 +37,7 @@ angle = {git = "https://github.com/servo/angle", branch = "servo"} freetype = { version = "0.2", default-features = false } [target.'cfg(target_os = "windows")'.dependencies] -servo-dwrote = "0.2" +dwrote = "0.3" [target.'cfg(target_os = "macos")'.dependencies] core-graphics = "0.7.0" diff --git a/gfx/webrender/res/ps_composite.fs.glsl b/gfx/webrender/res/ps_composite.fs.glsl index 89a71912136c..d97337bdf461 100644 --- a/gfx/webrender/res/ps_composite.fs.glsl +++ b/gfx/webrender/res/ps_composite.fs.glsl @@ -151,6 +151,22 @@ vec3 Luminosity(vec3 Cb, vec3 Cs) { return SetLum(Cb, Lum(Cs)); } +const int MixBlendMode_Multiply = 1; +const int MixBlendMode_Screen = 2; +const int MixBlendMode_Overlay = 3; +const int MixBlendMode_Darken = 4; +const int MixBlendMode_Lighten = 5; +const int MixBlendMode_ColorDodge = 6; +const int MixBlendMode_ColorBurn = 7; +const int MixBlendMode_HardLight = 8; +const int MixBlendMode_SoftLight = 9; +const int MixBlendMode_Difference = 10; +const int MixBlendMode_Exclusion = 11; +const int MixBlendMode_Hue = 12; +const int MixBlendMode_Saturation = 13; +const int MixBlendMode_Color = 14; +const int MixBlendMode_Luminosity = 15; + void main(void) { vec4 Cb = texture(sCache, vUv0); vec4 Cs = texture(sCache, vUv1); @@ -159,60 +175,62 @@ void main(void) { vec4 result = vec4(1.0, 1.0, 0.0, 1.0); switch (vOp) { - case 1: + case MixBlendMode_Multiply: result.rgb = Multiply(Cb.rgb, Cs.rgb); break; - case 2: + case MixBlendMode_Screen: result.rgb = Screen(Cb.rgb, Cs.rgb); break; - case 3: - result.rgb = HardLight(Cs.rgb, Cb.rgb); // Overlay is inverse of Hardlight + case MixBlendMode_Overlay: + // Overlay is inverse of Hardlight + result.rgb = HardLight(Cs.rgb, Cb.rgb); break; - case 4: - // mix-blend-mode: darken + case MixBlendMode_Darken: result.rgb = min(Cs.rgb, Cb.rgb); break; - case 5: - // mix-blend-mode: lighten + case MixBlendMode_Lighten: result.rgb = max(Cs.rgb, Cb.rgb); break; - case 6: + case MixBlendMode_ColorDodge: result.r = ColorDodge(Cb.r, Cs.r); result.g = ColorDodge(Cb.g, Cs.g); result.b = ColorDodge(Cb.b, Cs.b); break; - case 7: + case MixBlendMode_ColorBurn: result.r = ColorBurn(Cb.r, Cs.r); result.g = ColorBurn(Cb.g, Cs.g); result.b = ColorBurn(Cb.b, Cs.b); break; - case 8: + case MixBlendMode_HardLight: result.rgb = HardLight(Cb.rgb, Cs.rgb); break; - case 9: + case MixBlendMode_SoftLight: result.r = SoftLight(Cb.r, Cs.r); result.g = SoftLight(Cb.g, Cs.g); result.b = SoftLight(Cb.b, Cs.b); break; - case 10: + case MixBlendMode_Difference: result.rgb = Difference(Cb.rgb, Cs.rgb); break; - case 11: + case MixBlendMode_Exclusion: result.rgb = Exclusion(Cb.rgb, Cs.rgb); break; - case 12: + case MixBlendMode_Hue: result.rgb = Hue(Cb.rgb, Cs.rgb); break; - case 13: + case MixBlendMode_Saturation: result.rgb = Saturation(Cb.rgb, Cs.rgb); break; - case 14: + case MixBlendMode_Color: result.rgb = Color(Cb.rgb, Cs.rgb); break; - case 15: + case MixBlendMode_Luminosity: result.rgb = Luminosity(Cb.rgb, Cs.rgb); break; } + result.rgb = (1.0 - Cb.a) * Cs.rgb + Cb.a * result.rgb; + result.a = Cs.a; + oFragColor = result; } diff --git a/gfx/webrender/res/ps_composite.vs.glsl b/gfx/webrender/res/ps_composite.vs.glsl index 7e85129ae60c..2dfa41496037 100644 --- a/gfx/webrender/res/ps_composite.vs.glsl +++ b/gfx/webrender/res/ps_composite.vs.glsl @@ -19,8 +19,8 @@ void main(void) { vec2 texture_size = vec2(textureSize(sCache, 0)); - vec2 st0 = (backdrop_task.render_target_origin + vec2(0.0, backdrop_task.size.y)) / texture_size; - vec2 st1 = (backdrop_task.render_target_origin + vec2(backdrop_task.size.x, 0.0)) / texture_size; + vec2 st0 = backdrop_task.render_target_origin / texture_size; + vec2 st1 = (backdrop_task.render_target_origin + backdrop_task.size) / texture_size; vUv0 = vec3(mix(st0, st1, aPosition.xy), backdrop_task.render_target_layer_index); st0 = src_task.render_target_origin / texture_size; diff --git a/gfx/webrender/src/clip_scroll_node.rs b/gfx/webrender/src/clip_scroll_node.rs index 2d59346713d2..1d3de040049b 100644 --- a/gfx/webrender/src/clip_scroll_node.rs +++ b/gfx/webrender/src/clip_scroll_node.rs @@ -5,10 +5,9 @@ use euclid::Point3D; use geometry::ray_intersects_rect; use spring::{DAMPING, STIFFNESS, Spring}; -use webrender_traits::{LayerPoint, LayerRect, LayerSize, LayerToScrollTransform}; +use webrender_traits::{LayerPixel, LayerPoint, LayerRect, LayerSize, LayerToScrollTransform}; use webrender_traits::{LayerToWorldTransform, PipelineId, ScrollEventPhase, ScrollLayerId}; -use webrender_traits::{ScrollLayerRect, ScrollLocation, ScrollToWorldTransform, WorldPoint}; -use webrender_traits::{WorldPoint4D}; +use webrender_traits::{ScrollLayerRect, ScrollLocation, WorldPoint, WorldPoint4D}; #[cfg(target_os = "macos")] const CAN_OVERSCROLL: bool = true; @@ -16,6 +15,15 @@ const CAN_OVERSCROLL: bool = true; #[cfg(not(target_os = "macos"))] const CAN_OVERSCROLL: bool = false; +#[derive(Clone)] +pub enum NodeType { + /// Transform for this layer, relative to parent reference frame. A reference + /// frame establishes a new coordinate space in the tree. + ReferenceFrame(LayerToScrollTransform), + + /// Other nodes just do clipping, but no transformation. + ClipRect, +} /// Contains scrolling and transform information stacking contexts. #[derive(Clone)] @@ -26,44 +34,72 @@ pub struct ClipScrollNode { /// Size of the content inside the scroll region (in logical pixels) pub content_size: LayerSize, - /// Viewing rectangle + /// Viewing rectangle in the coordinate system of the parent reference frame. pub local_viewport_rect: LayerRect, - /// Viewing rectangle clipped against parent layer(s) + /// Clip rect of this node - typically the same as viewport rect, except + /// in overscroll cases. + pub local_clip_rect: LayerRect, + + /// Viewport rectangle clipped against parent layer(s) viewport rectangles. + /// This is in the coordinate system of the parent reference frame. pub combined_local_viewport_rect: LayerRect, - /// World transform for the viewport rect itself. + /// World transform for the viewport rect itself. This is the parent + /// reference frame transformation plus the scrolling offsets provided by + /// the nodes in between the reference frame and this node. pub world_viewport_transform: LayerToWorldTransform, - /// World transform for content within this layer + /// World transform for content transformed by this node. pub world_content_transform: LayerToWorldTransform, - /// Transform for this layer, relative to parent scrollable layer. - pub local_transform: LayerToScrollTransform, - /// Pipeline that this layer belongs to pub pipeline_id: PipelineId, /// Child layers pub children: Vec, + + /// Whether or not this node is a reference frame. + pub node_type: NodeType, } impl ClipScrollNode { pub fn new(local_viewport_rect: &LayerRect, + local_clip_rect: &LayerRect, content_size: LayerSize, - local_transform: &LayerToScrollTransform, pipeline_id: PipelineId) -> ClipScrollNode { ClipScrollNode { scrolling: ScrollingState::new(), content_size: content_size, local_viewport_rect: *local_viewport_rect, - combined_local_viewport_rect: *local_viewport_rect, + local_clip_rect: *local_clip_rect, + combined_local_viewport_rect: *local_clip_rect, world_viewport_transform: LayerToWorldTransform::identity(), world_content_transform: LayerToWorldTransform::identity(), - local_transform: *local_transform, children: Vec::new(), pipeline_id: pipeline_id, + node_type: NodeType::ClipRect, + } + } + + pub fn new_reference_frame(local_viewport_rect: &LayerRect, + local_clip_rect: &LayerRect, + content_size: LayerSize, + local_transform: &LayerToScrollTransform, + pipeline_id: PipelineId) + -> ClipScrollNode { + ClipScrollNode { + scrolling: ScrollingState::new(), + content_size: content_size, + local_viewport_rect: *local_viewport_rect, + local_clip_rect: *local_clip_rect, + combined_local_viewport_rect: *local_clip_rect, + world_viewport_transform: LayerToWorldTransform::identity(), + world_content_transform: LayerToWorldTransform::identity(), + children: Vec::new(), + pipeline_id: pipeline_id, + node_type: NodeType::ReferenceFrame(*local_transform), } } @@ -117,9 +153,16 @@ impl ClipScrollNode { } pub fn update_transform(&mut self, - parent_world_transform: &ScrollToWorldTransform, - parent_viewport_rect: &ScrollLayerRect) { - let inv_transform = match self.local_transform.inverse() { + parent_reference_frame_transform: &LayerToWorldTransform, + parent_combined_viewport_rect: &ScrollLayerRect, + parent_accumulated_scroll_offset: LayerPoint) { + + let local_transform = match self.node_type { + NodeType::ReferenceFrame(transform) => transform, + NodeType::ClipRect => LayerToScrollTransform::identity(), + }; + + let inv_transform = match local_transform.inverse() { Some(transform) => transform, None => { // If a transform function causes the current transformation matrix of an object @@ -129,18 +172,40 @@ impl ClipScrollNode { } }; - let parent_viewport_rect_in_local_space = inv_transform.transform_rect(parent_viewport_rect) - .translate(&-self.scrolling.offset); - let local_viewport_rect = self.local_viewport_rect.translate(&-self.scrolling.offset); - let viewport_rect = parent_viewport_rect_in_local_space.intersection(&local_viewport_rect) - .unwrap_or(LayerRect::zero()); + // We are trying to move the combined viewport rectangle of our parent nodes into the + // coordinate system of this node, so we must invert our transformation (only for + // reference frames) and then apply the scroll offset of all the parent layers. + let parent_combined_viewport_in_local_space = + inv_transform.pre_translated(-parent_accumulated_scroll_offset.x, + -parent_accumulated_scroll_offset.y, + 0.0) + .transform_rect(parent_combined_viewport_rect); - self.combined_local_viewport_rect = viewport_rect; - self.world_viewport_transform = parent_world_transform.pre_mul(&self.local_transform); - self.world_content_transform = self.world_viewport_transform - .pre_translated(self.scrolling.offset.x, - self.scrolling.offset.y, - 0.0); + // Now that we have the combined viewport rectangle of the parent nodes in local space, + // we do the intersection and get our combined viewport rect in the coordinate system + // starting from our origin. + self.combined_local_viewport_rect = + parent_combined_viewport_in_local_space.intersection(&self.local_clip_rect) + .unwrap_or(LayerRect::zero()); + + // The transformation for this viewport in world coordinates is the transformation for + // our parent reference frame, plus any accumulated scrolling offsets from nodes + // between our reference frame and this node. For reference frames, we also include + // whatever local transformation this reference frame provides. This can be combined + // with the local_viewport_rect to get its position in world space. + self.world_viewport_transform = + parent_reference_frame_transform + .pre_translated(parent_accumulated_scroll_offset.x, + parent_accumulated_scroll_offset.y, + 0.0) + .pre_mul(&local_transform.with_destination::()); + + // The transformation for any content inside of us is the viewport transformation, plus + // whatever scrolling offset we supply as well. + self.world_content_transform = + self.world_viewport_transform.pre_translated(self.scrolling.offset.x, + self.scrolling.offset.y, + 0.0); } pub fn scrollable_height(&self) -> f32 { diff --git a/gfx/webrender/src/clip_scroll_tree.rs b/gfx/webrender/src/clip_scroll_tree.rs index b34cf7bcd569..706c15b4eb52 100644 --- a/gfx/webrender/src/clip_scroll_tree.rs +++ b/gfx/webrender/src/clip_scroll_tree.rs @@ -2,13 +2,13 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +use clip_scroll_node::{ClipScrollNode, NodeType, ScrollingState}; use fnv::FnvHasher; -use clip_scroll_node::{ClipScrollNode, ScrollingState}; use std::collections::{HashMap, HashSet}; use std::hash::BuildHasherDefault; -use webrender_traits::{LayerPoint, LayerRect, LayerSize, LayerToScrollTransform, PipelineId}; -use webrender_traits::{ScrollEventPhase, ScrollLayerId, ScrollLayerInfo, ScrollLayerPixel}; -use webrender_traits::{ScrollLayerRect, ScrollLayerState, ScrollLocation, ScrollToWorldTransform}; +use webrender_traits::{LayerPoint, LayerRect, LayerSize, LayerToScrollTransform}; +use webrender_traits::{LayerToWorldTransform, PipelineId, ScrollEventPhase, ScrollLayerId}; +use webrender_traits::{ScrollLayerInfo, ScrollLayerRect, ScrollLayerState, ScrollLocation}; use webrender_traits::{ServoScrollRootId, WorldPoint, as_scroll_parent_rect}; pub type ScrollStates = HashMap>; @@ -70,18 +70,25 @@ impl ClipScrollTree { pub fn establish_root(&mut self, pipeline_id: PipelineId, viewport_size: &LayerSize, + viewport_offset: LayerPoint, + clip_size: LayerSize, content_size: &LayerSize) { debug_assert!(self.nodes.is_empty()); - let identity = LayerToScrollTransform::identity(); + let transform = LayerToScrollTransform::create_translation(viewport_offset.x, viewport_offset.y, 0.0); let viewport = LayerRect::new(LayerPoint::zero(), *viewport_size); - + let clip = LayerRect::new(LayerPoint::new(-viewport_offset.x, -viewport_offset.y), + LayerSize::new(clip_size.width, clip_size.height)); let root_reference_frame_id = ScrollLayerId::root_reference_frame(pipeline_id); self.root_reference_frame_id = root_reference_frame_id; - let reference_frame = ClipScrollNode::new(&viewport, viewport.size, &identity, pipeline_id); + let reference_frame = ClipScrollNode::new_reference_frame(&viewport, + &clip, + viewport.size, + &transform, + pipeline_id); self.nodes.insert(self.root_reference_frame_id, reference_frame); - let scroll_node = ClipScrollNode::new(&viewport, *content_size, &identity, pipeline_id); + let scroll_node = ClipScrollNode::new(&viewport, &clip, *content_size, pipeline_id); let topmost_scroll_layer_id = ScrollLayerId::root_scroll_layer(pipeline_id); self.topmost_scroll_layer_id = topmost_scroll_layer_id; self.add_node(scroll_node, topmost_scroll_layer_id, root_reference_frame_id); @@ -294,25 +301,43 @@ impl ClipScrollTree { } let root_reference_frame_id = self.root_reference_frame_id(); - let root_viewport = self.nodes[&root_reference_frame_id].local_viewport_rect; + let root_viewport = self.nodes[&root_reference_frame_id].local_clip_rect; self.update_node_transform(root_reference_frame_id, - &ScrollToWorldTransform::identity(), - &as_scroll_parent_rect(&root_viewport)); + &LayerToWorldTransform::identity(), + &as_scroll_parent_rect(&root_viewport), + LayerPoint::zero()); } fn update_node_transform(&mut self, layer_id: ScrollLayerId, - parent_world_transform: &ScrollToWorldTransform, - parent_viewport_rect: &ScrollLayerRect) { + parent_reference_frame_transform: &LayerToWorldTransform, + parent_viewport_rect: &ScrollLayerRect, + parent_accumulated_scroll_offset: LayerPoint) { // TODO(gw): This is an ugly borrow check workaround to clone these. // Restructure this to avoid the clones! - let (node_transform_for_children, viewport_rect, node_children) = { + let (reference_frame_transform, viewport_rect, accumulated_scroll_offset, node_children) = { match self.nodes.get_mut(&layer_id) { Some(node) => { - node.update_transform(parent_world_transform, parent_viewport_rect); + node.update_transform(parent_reference_frame_transform, + parent_viewport_rect, + parent_accumulated_scroll_offset); - (node.world_content_transform.with_source::(), + // The transformation we are passing is the transformation of the parent + // reference frame and the offset is the accumulated offset of all the nodes + // between us and the parent reference frame. If we are a reference frame, + // we need to reset both these values. + let (transform, offset) = match node.node_type { + NodeType::ReferenceFrame(..) => + (node.world_viewport_transform, LayerPoint::zero()), + NodeType::ClipRect => { + (*parent_reference_frame_transform, + parent_accumulated_scroll_offset + node.scrolling.offset) + } + }; + + (transform, as_scroll_parent_rect(&node.combined_local_viewport_rect), + offset, node.children.clone()) } None => return, @@ -321,8 +346,9 @@ impl ClipScrollTree { for child_layer_id in node_children { self.update_node_transform(child_layer_id, - &node_transform_for_children, - &viewport_rect); + &reference_frame_transform, + &viewport_rect, + accumulated_scroll_offset); } } @@ -369,7 +395,7 @@ impl ClipScrollTree { }; self.current_reference_frame_id += 1; - let node = ClipScrollNode::new(&rect, rect.size, &transform, pipeline_id); + let node = ClipScrollNode::new_reference_frame(&rect, &rect, rect.size, &transform, pipeline_id); self.add_node(node, reference_frame_id, parent_id); reference_frame_id } diff --git a/gfx/webrender/src/device.rs b/gfx/webrender/src/device.rs index 0fbfa0b81be1..194d88749ea1 100644 --- a/gfx/webrender/src/device.rs +++ b/gfx/webrender/src/device.rs @@ -1886,6 +1886,30 @@ impl Device { } } + pub fn clear_target_rect(&self, + color: Option<[f32; 4]>, + depth: Option, + rect: DeviceIntRect) { + let mut clear_bits = 0; + + if let Some(color) = color { + gl::clear_color(color[0], color[1], color[2], color[3]); + clear_bits |= gl::COLOR_BUFFER_BIT; + } + + if let Some(depth) = depth { + gl::clear_depth(depth as f64); + clear_bits |= gl::DEPTH_BUFFER_BIT; + } + + if clear_bits != 0 { + gl::enable(gl::SCISSOR_TEST); + gl::scissor(rect.origin.x, rect.origin.y, rect.size.width, rect.size.height); + gl::clear(clear_bits); + gl::disable(gl::SCISSOR_TEST); + } + } + pub fn enable_depth(&self) { gl::enable(gl::DEPTH_TEST); } diff --git a/gfx/webrender/src/frame.rs b/gfx/webrender/src/frame.rs index 54e2549a352c..7cae258eb236 100644 --- a/gfx/webrender/src/frame.rs +++ b/gfx/webrender/src/frame.rs @@ -20,7 +20,7 @@ use webrender_traits::{AuxiliaryLists, ClipRegion, ColorF, DisplayItem, Epoch, F use webrender_traits::{LayerPoint, LayerRect, LayerSize, LayerToScrollTransform, LayoutTransform, TileOffset}; use webrender_traits::{MixBlendMode, PipelineId, ScrollEventPhase, ScrollLayerId, ScrollLayerState}; use webrender_traits::{ScrollLocation, ScrollPolicy, ServoScrollRootId, SpecificDisplayItem}; -use webrender_traits::{StackingContext, WorldPoint, ImageDisplayItem, DeviceUintSize}; +use webrender_traits::{StackingContext, WorldPoint, ImageDisplayItem, DeviceUintRect, DeviceUintSize}; #[derive(Copy, Clone, PartialEq, PartialOrd, Debug)] pub struct FrameId(pub u32); @@ -228,7 +228,12 @@ impl Frame { self.clip_scroll_tree.discard_frame_state_for_pipeline(pipeline_id); } - pub fn create(&mut self, scene: &Scene, resource_cache: &mut ResourceCache) { + pub fn create(&mut self, + scene: &Scene, + resource_cache: &mut ResourceCache, + window_size: DeviceUintSize, + inner_rect: DeviceUintRect, + device_pixel_ratio: f32) { let root_pipeline_id = match scene.root_pipeline_id { Some(root_pipeline_id) => root_pipeline_id, None => return, @@ -245,6 +250,11 @@ impl Frame { None => return, }; + if window_size.width == 0 || window_size.height == 0 { + println!("ERROR: Invalid window dimensions! Please call api.set_window_size()"); + return; + } + let old_scrolling_states = self.reset(); self.pipeline_auxiliary_lists = scene.pipeline_auxiliary_lists.clone(); @@ -258,8 +268,19 @@ impl Frame { } }; + let inner_origin = inner_rect.origin.to_f32(); + let viewport_offset = LayerPoint::new((inner_origin.x / device_pixel_ratio).round(), + (inner_origin.y / device_pixel_ratio).round()); + let outer_size = window_size.to_f32(); + let outer_size = LayerSize::new((outer_size.width / device_pixel_ratio).round(), + (outer_size.height / device_pixel_ratio).round()); + let clip_size = LayerSize::new(outer_size.width + 2.0 * viewport_offset.x, + outer_size.height + 2.0 * viewport_offset.y); + self.clip_scroll_tree.establish_root(root_pipeline_id, &root_pipeline.viewport_size, + viewport_offset, + clip_size, &root_clip.main.size); let background_color = root_pipeline.background_color.and_then(|color| { @@ -270,7 +291,7 @@ impl Frame { } }); - let mut frame_builder = FrameBuilder::new(root_pipeline.viewport_size, + let mut frame_builder = FrameBuilder::new(window_size, background_color, self.frame_builder_config); @@ -288,21 +309,15 @@ impl Frame { let viewport_rect = LayerRect::new(LayerPoint::zero(), root_pipeline.viewport_size); let clip = ClipRegion::simple(&viewport_rect); - context.builder.push_clip_scroll_node(reference_frame_id, - &clip, - &LayerPoint::zero(), - &root_pipeline.viewport_size); - context.builder.push_clip_scroll_node(topmost_scroll_layer_id, - &clip, - &LayerPoint::zero(), - &root_clip.main.size); + context.builder.push_clip_scroll_node(reference_frame_id, &clip); + context.builder.push_clip_scroll_node(topmost_scroll_layer_id, &clip); self.flatten_stacking_context(&mut traversal, root_pipeline_id, &mut context, reference_frame_id, topmost_scroll_layer_id, - LayerToScrollTransform::identity(), + LayerPoint::zero(), 0, &root_stacking_context, root_clip); @@ -321,7 +336,7 @@ impl Frame { context: &mut FlattenContext, current_reference_frame_id: ScrollLayerId, parent_scroll_layer_id: ScrollLayerId, - layer_relative_transform: LayerToScrollTransform, + reference_frame_relative_offset: LayerPoint, level: i32, clip: &ClipRegion, content_size: &LayerSize, @@ -332,23 +347,17 @@ impl Frame { return; } - let clip_rect = clip.main; - let node = ClipScrollNode::new(&clip_rect, - *content_size, - &layer_relative_transform, - pipeline_id); + let clip_rect = clip.main.translate(&reference_frame_relative_offset); + let node = ClipScrollNode::new(&clip_rect, &clip_rect, *content_size, pipeline_id); self.clip_scroll_tree.add_node(node, new_scroll_layer_id, parent_scroll_layer_id); - context.builder.push_clip_scroll_node(new_scroll_layer_id, - clip, - &clip_rect.origin, - &content_size); + context.builder.push_clip_scroll_node(new_scroll_layer_id, clip); self.flatten_items(traversal, pipeline_id, context, current_reference_frame_id, new_scroll_layer_id, - LayerToScrollTransform::identity(), + reference_frame_relative_offset, level); context.builder.pop_clip_scroll_node(); @@ -360,7 +369,7 @@ impl Frame { context: &mut FlattenContext, current_reference_frame_id: ScrollLayerId, current_scroll_layer_id: ScrollLayerId, - layer_relative_transform: LayerToScrollTransform, + mut reference_frame_relative_offset: LayerPoint, level: i32, stacking_context: &StackingContext, clip_region: &ClipRegion) { @@ -384,17 +393,6 @@ impl Frame { return; } - let stacking_context_transform = context.scene - .properties - .resolve_layout_transform(&stacking_context.transform); - - let mut transform = - layer_relative_transform.pre_translated(stacking_context.bounds.origin.x, - stacking_context.bounds.origin.y, - 0.0) - .pre_mul(&stacking_context_transform) - .pre_mul(&stacking_context.perspective); - let mut reference_frame_id = current_reference_frame_id; let mut scroll_layer_id = match stacking_context.scroll_policy { ScrollPolicy::Fixed => current_reference_frame_id, @@ -403,32 +401,48 @@ impl Frame { // If we have a transformation, we establish a new reference frame. This means // that fixed position stacking contexts are positioned relative to us. - if stacking_context_transform != LayoutTransform::identity() || - stacking_context.perspective != LayoutTransform::identity() { + if stacking_context.transform.is_some() || stacking_context.perspective.is_some() { + let transform = stacking_context.transform.as_ref(); + let transform = context.scene.properties.resolve_layout_transform(transform); + let perspective = + stacking_context.perspective.unwrap_or_else(LayoutTransform::identity); + let transform = + LayerToScrollTransform::create_translation(reference_frame_relative_offset.x, + reference_frame_relative_offset.y, + 0.0) + .pre_translated(stacking_context.bounds.origin.x, + stacking_context.bounds.origin.y, + 0.0) + .pre_mul(&transform) + .pre_mul(&perspective); scroll_layer_id = self.clip_scroll_tree.add_reference_frame(clip_region.main, transform, pipeline_id, scroll_layer_id); reference_frame_id = scroll_layer_id; - transform = LayerToScrollTransform::identity(); + reference_frame_relative_offset = LayerPoint::zero(); + } else { + reference_frame_relative_offset = LayerPoint::new( + reference_frame_relative_offset.x + stacking_context.bounds.origin.x, + reference_frame_relative_offset.y + stacking_context.bounds.origin.y); } if level == 0 { if let Some(pipeline) = context.scene.pipeline_map.get(&pipeline_id) { if let Some(bg_color) = pipeline.background_color { - // Adding a dummy layer for this rectangle in order to disable clipping. - let no_clip = ClipRegion::simple(&clip_region.main); - context.builder.push_stacking_context(clip_region.main, - transform, + context.builder.push_stacking_context(reference_frame_relative_offset, + clip_region.main, pipeline_id, - scroll_layer_id, + false, CompositeOps::empty()); - //Note: we don't use the original clip region here, + // Note: we don't use the original clip region here, // it's already processed by the node we just pushed. - context.builder.add_solid_rectangle(&clip_region.main, - &no_clip, + let background_rect = LayerRect::new(LayerPoint::zero(), clip_region.main.size); + context.builder.add_solid_rectangle(scroll_layer_id, + &clip_region.main, + &ClipRegion::simple(&background_rect), &bg_color, PrimitiveFlags::None); @@ -438,10 +452,10 @@ impl Frame { } // TODO(gw): Int with overflow etc - context.builder.push_stacking_context(clip_region.main, - transform, + context.builder.push_stacking_context(reference_frame_relative_offset, + clip_region.main, pipeline_id, - scroll_layer_id, + level == 0, composition_operations); self.flatten_items(traversal, @@ -449,12 +463,13 @@ impl Frame { context, reference_frame_id, scroll_layer_id, - transform, + reference_frame_relative_offset, level); if level == 0 && self.frame_builder_config.enable_scrollbars { let scrollbar_rect = LayerRect::new(LayerPoint::zero(), LayerSize::new(10.0, 70.0)); context.builder.add_solid_rectangle( + scroll_layer_id, &scrollbar_rect, &ClipRegion::simple(&scrollbar_rect), &DEFAULT_SCROLLBAR_COLOR, @@ -469,7 +484,7 @@ impl Frame { bounds: &LayerRect, context: &mut FlattenContext, current_scroll_layer_id: ScrollLayerId, - layer_relative_transform: LayerToScrollTransform) { + reference_frame_relative_offset: LayerPoint) { let pipeline = match context.scene.pipeline_map.get(&pipeline_id) { Some(pipeline) => pipeline, @@ -493,9 +508,10 @@ impl Frame { self.pipeline_epoch_map.insert(pipeline_id, pipeline.epoch); let iframe_rect = LayerRect::new(LayerPoint::zero(), bounds.size); - let transform = layer_relative_transform.pre_translated(bounds.origin.x, - bounds.origin.y, - 0.0); + let transform = LayerToScrollTransform::create_translation( + reference_frame_relative_offset.x + bounds.origin.x, + reference_frame_relative_offset.y + bounds.origin.y, + 0.0); let iframe_reference_frame_id = self.clip_scroll_tree.add_reference_frame(iframe_rect, transform, @@ -503,21 +519,15 @@ impl Frame { current_scroll_layer_id); let iframe_scroll_layer_id = ScrollLayerId::root_scroll_layer(pipeline_id); let node = ClipScrollNode::new(&LayerRect::new(LayerPoint::zero(), iframe_rect.size), + &LayerRect::new(LayerPoint::zero(), iframe_rect.size), iframe_clip.main.size, - &LayerToScrollTransform::identity(), pipeline_id); self.clip_scroll_tree.add_node(node.clone(), iframe_scroll_layer_id, iframe_reference_frame_id); - context.builder.push_clip_scroll_node(iframe_reference_frame_id, - iframe_clip, - &LayerPoint::zero(), - &iframe_rect.size); - context.builder.push_clip_scroll_node(iframe_scroll_layer_id, - iframe_clip, - &LayerPoint::zero(), - &iframe_clip.main.size); + context.builder.push_clip_scroll_node(iframe_reference_frame_id, iframe_clip); + context.builder.push_clip_scroll_node(iframe_scroll_layer_id, iframe_clip); let mut traversal = DisplayListTraversal::new_skipping_first(display_list); @@ -526,7 +536,7 @@ impl Frame { context, iframe_reference_frame_id, iframe_scroll_layer_id, - LayerToScrollTransform::identity(), + LayerPoint::zero(), 0, &iframe_stacking_context, iframe_clip); @@ -541,13 +551,15 @@ impl Frame { context: &mut FlattenContext, current_reference_frame_id: ScrollLayerId, current_scroll_layer_id: ScrollLayerId, - layer_relative_transform: LayerToScrollTransform, + reference_frame_relative_offset: LayerPoint, level: i32) { while let Some(item) = traversal.next() { match item.item { SpecificDisplayItem::WebGL(ref info) => { - context.builder.add_webgl_rectangle(item.rect, - &item.clip, info.context_id); + context.builder.add_webgl_rectangle(current_scroll_layer_id, + item.rect, + &item.clip, + info.context_id); } SpecificDisplayItem::Image(ref info) => { let image = context.resource_cache.get_image_properties(info.image_key); @@ -555,9 +567,15 @@ impl Frame { // The image resource is tiled. We have to generate an image primitive // for each tile. let image_size = DeviceUintSize::new(image.descriptor.width, image.descriptor.height); - self.decompose_tiled_image(context, &item, info, image_size, tile_size as u32); + self.decompose_tiled_image(current_scroll_layer_id, + context, + &item, + info, + image_size, + tile_size as u32); } else { - context.builder.add_image(item.rect, + context.builder.add_image(current_scroll_layer_id, + item.rect, &item.clip, &info.stretch_size, &info.tile_spacing, @@ -568,7 +586,8 @@ impl Frame { } } SpecificDisplayItem::YuvImage(ref info) => { - context.builder.add_yuv_image(item.rect, + context.builder.add_yuv_image(current_scroll_layer_id, + item.rect, &item.clip, info.y_image_key, info.u_image_key, @@ -576,7 +595,8 @@ impl Frame { info.color_space); } SpecificDisplayItem::Text(ref text_info) => { - context.builder.add_text(item.rect, + context.builder.add_text(current_scroll_layer_id, + item.rect, &item.clip, text_info.font_key, text_info.size, @@ -586,13 +606,15 @@ impl Frame { text_info.glyph_options); } SpecificDisplayItem::Rectangle(ref info) => { - context.builder.add_solid_rectangle(&item.rect, + context.builder.add_solid_rectangle(current_scroll_layer_id, + &item.rect, &item.clip, &info.color, PrimitiveFlags::None); } SpecificDisplayItem::Gradient(ref info) => { - context.builder.add_gradient(item.rect, + context.builder.add_gradient(current_scroll_layer_id, + item.rect, &item.clip, info.start_point, info.end_point, @@ -600,7 +622,8 @@ impl Frame { info.extend_mode); } SpecificDisplayItem::RadialGradient(ref info) => { - context.builder.add_radial_gradient(item.rect, + context.builder.add_radial_gradient(current_scroll_layer_id, + item.rect, &item.clip, info.start_center, info.start_radius, @@ -610,7 +633,8 @@ impl Frame { info.extend_mode); } SpecificDisplayItem::BoxShadow(ref box_shadow_info) => { - context.builder.add_box_shadow(&box_shadow_info.box_bounds, + context.builder.add_box_shadow(current_scroll_layer_id, + &box_shadow_info.box_bounds, &item.clip, &box_shadow_info.offset, &box_shadow_info.color, @@ -620,7 +644,10 @@ impl Frame { box_shadow_info.clip_mode); } SpecificDisplayItem::Border(ref info) => { - context.builder.add_border(item.rect, &item.clip, info); + context.builder.add_border(current_scroll_layer_id, + item.rect, + &item.clip, + info); } SpecificDisplayItem::PushStackingContext(ref info) => { self.flatten_stacking_context(traversal, @@ -628,7 +655,7 @@ impl Frame { context, current_reference_frame_id, current_scroll_layer_id, - layer_relative_transform, + reference_frame_relative_offset, level + 1, &info.stacking_context, &item.clip); @@ -639,7 +666,7 @@ impl Frame { context, current_reference_frame_id, current_scroll_layer_id, - layer_relative_transform, + reference_frame_relative_offset, level, &item.clip, &info.content_size, @@ -650,7 +677,7 @@ impl Frame { &item.rect, context, current_scroll_layer_id, - layer_relative_transform); + reference_frame_relative_offset); } SpecificDisplayItem::PopStackingContext | SpecificDisplayItem::PopScrollLayer => return, @@ -659,6 +686,7 @@ impl Frame { } fn decompose_tiled_image(&mut self, + scroll_layer_id: ScrollLayerId, context: &mut FlattenContext, item: &DisplayItem, info: &ImageDisplayItem, @@ -749,7 +777,10 @@ impl Frame { for ty in 0..num_tiles_y { for tx in 0..num_tiles_x { - self.add_tile_primitive(context, item, info, + self.add_tile_primitive(scroll_layer_id, + context, + item, + info, TileOffset::new(tx, ty), stretched_tile_size, 1.0, 1.0, @@ -757,7 +788,10 @@ impl Frame { } if leftover.width != 0 { // Tiles on the right edge that are smaller than the tile size. - self.add_tile_primitive(context, item, info, + self.add_tile_primitive(scroll_layer_id, + context, + item, + info, TileOffset::new(num_tiles_x, ty), stretched_tile_size, (leftover.width as f32) / tile_size_f32, @@ -769,27 +803,36 @@ impl Frame { if leftover.height != 0 { for tx in 0..num_tiles_x { // Tiles on the bottom edge that are smaller than the tile size. - self.add_tile_primitive(context, item, info, + self.add_tile_primitive(scroll_layer_id, + context, + item, + info, TileOffset::new(tx, num_tiles_y), stretched_tile_size, 1.0, (leftover.height as f32) / tile_size_f32, - repeat_x, repeat_y); + repeat_x, + repeat_y); } if leftover.width != 0 { // Finally, the bottom-right tile with a "leftover" size. - self.add_tile_primitive(context, item, info, + self.add_tile_primitive(scroll_layer_id, + context, + item, + info, TileOffset::new(num_tiles_x, num_tiles_y), stretched_tile_size, (leftover.width as f32) / tile_size_f32, (leftover.height as f32) / tile_size_f32, - repeat_x, repeat_y); + repeat_x, + repeat_y); } } } fn add_tile_primitive(&mut self, + scroll_layer_id: ScrollLayerId, context: &mut FlattenContext, item: &DisplayItem, info: &ImageDisplayItem, @@ -833,7 +876,8 @@ impl Frame { // Fix up the primitive's rect if it overflows the original item rect. if let Some(prim_rect) = prim_rect.intersection(&item.rect) { - context.builder.add_image(prim_rect, + context.builder.add_image(scroll_layer_id, + prim_rect, &item.clip, &stretched_size, &info.tile_spacing, diff --git a/gfx/webrender/src/frame_builder.rs b/gfx/webrender/src/frame_builder.rs index 7700c221bc3c..56772b50710c 100644 --- a/gfx/webrender/src/frame_builder.rs +++ b/gfx/webrender/src/frame_builder.rs @@ -24,14 +24,14 @@ use tiling::{AuxiliaryListsMap, ClipScrollGroup, ClipScrollGroupIndex, Composite use tiling::{PackedLayer, PackedLayerIndex, PrimitiveFlags, PrimitiveRunCmd, RenderPass}; use tiling::{RenderTargetContext, RenderTaskCollection, ScrollbarPrimitive, ScrollLayer}; use tiling::{ScrollLayerIndex, StackingContext, StackingContextIndex}; -use util::{self, pack_as_float, rect_from_points_f, subtract_rect, TransformedRect}; +use util::{self, pack_as_float, rect_from_points_f, subtract_rect}; use util::{RectHelpers, TransformedRectKind}; -use webrender_traits::{as_scroll_parent_rect, BorderDetails, BorderDisplayItem, BorderSide, BorderStyle}; -use webrender_traits::{BoxShadowClipMode, ClipRegion, ColorF, device_length, DeviceIntPoint}; +use webrender_traits::{BorderDetails, BorderDisplayItem, BorderSide, BorderStyle}; +use webrender_traits::{BoxShadowClipMode, ClipRegion, ColorF, DeviceIntPoint}; use webrender_traits::{DeviceIntRect, DeviceIntSize, DeviceUintSize, ExtendMode, FontKey, TileOffset}; use webrender_traits::{FontRenderMode, GlyphOptions, ImageKey, ImageRendering, ItemRange}; -use webrender_traits::{LayerPoint, LayerRect, LayerSize, LayerToScrollTransform, PipelineId}; -use webrender_traits::{RepeatMode, ScrollLayerId, ScrollLayerPixel, WebGLContextId, YuvColorSpace}; +use webrender_traits::{LayerPoint, LayerRect, LayerSize, PipelineId, RepeatMode, ScrollLayerId}; +use webrender_traits::{WebGLContextId, YuvColorSpace}; #[derive(Debug, Clone)] struct ImageBorderSegment { @@ -102,7 +102,7 @@ impl FrameBuilderConfig { } pub struct FrameBuilder { - screen_rect: LayerRect, + screen_size: DeviceUintSize, background_color: Option, prim_store: PrimitiveStore, cmds: Vec, @@ -118,14 +118,18 @@ pub struct FrameBuilder { /// A stack of scroll nodes used during display list processing to properly /// parent new scroll nodes. clip_scroll_node_stack: Vec, + + /// A stack of stacking contexts used for creating ClipScrollGroups as + /// primitives are added to the frame. + stacking_context_stack: Vec, } impl FrameBuilder { - pub fn new(viewport_size: LayerSize, + pub fn new(screen_size: DeviceUintSize, background_color: Option, config: FrameBuilderConfig) -> FrameBuilder { FrameBuilder { - screen_rect: LayerRect::new(LayerPoint::zero(), viewport_size), + screen_size: screen_size, background_color: background_color, stacking_context_store: Vec::new(), scroll_layer_store: Vec::new(), @@ -136,13 +140,24 @@ impl FrameBuilder { scrollbar_prims: Vec::new(), config: config, clip_scroll_node_stack: Vec::new(), + stacking_context_stack: Vec::new(), } } fn add_primitive(&mut self, + scroll_layer_id: ScrollLayerId, rect: &LayerRect, clip_region: &ClipRegion, - container: PrimitiveContainer) -> PrimitiveIndex { + container: PrimitiveContainer) + -> PrimitiveIndex { + let stacking_context_index = *self.stacking_context_stack.last().unwrap(); + if !self.stacking_context_store[stacking_context_index.0] + .has_clip_scroll_group(scroll_layer_id) { + let group_index = self.create_clip_scroll_group(stacking_context_index, + scroll_layer_id); + let stacking_context = &mut self.stacking_context_store[stacking_context_index.0]; + stacking_context.clip_scroll_groups.push(group_index); + } let geometry = PrimitiveGeometry { local_rect: *rect, @@ -163,7 +178,7 @@ impl FrameBuilder { container); match self.cmds.last_mut().unwrap() { - &mut PrimitiveRunCmd::PrimitiveRun(_run_prim_index, ref mut count) => { + &mut PrimitiveRunCmd::PrimitiveRun(_run_prim_index, ref mut count, _) => { debug_assert!(_run_prim_index.0 + *count == prim_index.0); *count += 1; return prim_index; @@ -174,15 +189,14 @@ impl FrameBuilder { &mut PrimitiveRunCmd::PopScrollLayer => {} } - self.cmds.push(PrimitiveRunCmd::PrimitiveRun(prim_index, 1)); + self.cmds.push(PrimitiveRunCmd::PrimitiveRun(prim_index, 1, scroll_layer_id)); prim_index } pub fn create_clip_scroll_group(&mut self, stacking_context_index: StackingContextIndex, - scroll_layer_id: ScrollLayerId, - pipeline_id: PipelineId) + scroll_layer_id: ScrollLayerId) -> ClipScrollGroupIndex { let packed_layer_index = PackedLayerIndex(self.packed_layers.len()); self.packed_layers.push(PackedLayer::empty()); @@ -191,40 +205,47 @@ impl FrameBuilder { stacking_context_index: stacking_context_index, scroll_layer_id: scroll_layer_id, packed_layer_index: packed_layer_index, - pipeline_id: pipeline_id, xf_rect: None, }); - ClipScrollGroupIndex(self.clip_scroll_group_store.len() - 1) + ClipScrollGroupIndex(self.clip_scroll_group_store.len() - 1, scroll_layer_id) } pub fn push_stacking_context(&mut self, + reference_frame_offset: LayerPoint, rect: LayerRect, - transform: LayerToScrollTransform, pipeline_id: PipelineId, - scroll_layer_id: ScrollLayerId, + is_page_root: bool, composite_ops: CompositeOps) { + if let Some(parent_index) = self.stacking_context_stack.last() { + let parent_is_root = self.stacking_context_store[parent_index.0].is_page_root; + + if composite_ops.mix_blend_mode.is_some() && !parent_is_root { + // the parent stacking context of a stacking context with mix-blend-mode + // must be drawn with a transparent background, unless the parent stacking context + // is the root of the page + self.stacking_context_store[parent_index.0].should_isolate = true; + } + } + let stacking_context_index = StackingContextIndex(self.stacking_context_store.len()); - let group_index = self.create_clip_scroll_group(stacking_context_index, - scroll_layer_id, - pipeline_id); self.stacking_context_store.push(StackingContext::new(pipeline_id, - transform, + reference_frame_offset, rect, - composite_ops, - group_index)); + is_page_root, + composite_ops)); self.cmds.push(PrimitiveRunCmd::PushStackingContext(stacking_context_index)); + self.stacking_context_stack.push(stacking_context_index); } pub fn pop_stacking_context(&mut self) { self.cmds.push(PrimitiveRunCmd::PopStackingContext); + self.stacking_context_stack.pop(); } pub fn push_clip_scroll_node(&mut self, scroll_layer_id: ScrollLayerId, - clip_region: &ClipRegion, - node_origin: &LayerPoint, - content_size: &LayerSize) { + clip_region: &ClipRegion) { let scroll_layer_index = ScrollLayerIndex(self.scroll_layer_store.len()); let parent_index = *self.clip_scroll_node_stack.last().unwrap_or(&scroll_layer_index); self.clip_scroll_node_stack.push(scroll_layer_index); @@ -246,29 +267,15 @@ impl FrameBuilder { }); self.packed_layers.push(PackedLayer::empty()); self.cmds.push(PrimitiveRunCmd::PushScrollLayer(scroll_layer_index)); - - - // We need to push a fake stacking context here, because primitives that are - // direct children of this stacking context, need to be adjusted by the scroll - // offset of this layer. Eventually we should be able to remove this. - let rect = LayerRect::new(LayerPoint::zero(), - LayerSize::new(content_size.width + node_origin.x, - content_size.height + node_origin.y)); - self.push_stacking_context(rect, - LayerToScrollTransform::identity(), - scroll_layer_id.pipeline_id, - scroll_layer_id, - CompositeOps::empty()); - } pub fn pop_clip_scroll_node(&mut self) { - self.pop_stacking_context(); self.cmds.push(PrimitiveRunCmd::PopScrollLayer); self.clip_scroll_node_stack.pop(); } pub fn add_solid_rectangle(&mut self, + scroll_layer_id: ScrollLayerId, rect: &LayerRect, clip_region: &ClipRegion, color: &ColorF, @@ -281,7 +288,8 @@ impl FrameBuilder { color: *color, }; - let prim_index = self.add_primitive(rect, + let prim_index = self.add_primitive(scroll_layer_id, + rect, clip_region, PrimitiveContainer::Rectangle(prim)); @@ -318,6 +326,7 @@ impl FrameBuilder { } pub fn add_border(&mut self, + scroll_layer_id: ScrollLayerId, rect: LayerRect, clip_region: &ClipRegion, border_item: &BorderDisplayItem) { @@ -411,7 +420,8 @@ impl FrameBuilder { } for segment in segments { - self.add_image(segment.geom_rect, + self.add_image(scroll_layer_id, + segment.geom_rect, clip_region, &segment.stretch_size, &segment.tile_spacing, @@ -492,7 +502,8 @@ impl FrameBuilder { ]; for rect in &rects { - self.add_solid_rectangle(rect, + self.add_solid_rectangle(scroll_layer_id, + rect, clip_region, &top_color, PrimitiveFlags::None); @@ -533,7 +544,8 @@ impl FrameBuilder { ], }; - self.add_primitive(&rect, + self.add_primitive(scroll_layer_id, + &rect, clip_region, PrimitiveContainer::Border(prim_cpu, prim_gpu)); } @@ -541,6 +553,7 @@ impl FrameBuilder { } pub fn add_gradient(&mut self, + scroll_layer_id: ScrollLayerId, rect: LayerRect, clip_region: &ClipRegion, start_point: LayerPoint, @@ -591,10 +604,11 @@ impl FrameBuilder { PrimitiveContainer::AngleGradient(gradient_cpu, gradient_gpu) }; - self.add_primitive(&rect, clip_region, prim); + self.add_primitive(scroll_layer_id, &rect, clip_region, prim); } pub fn add_radial_gradient(&mut self, + scroll_layer_id: ScrollLayerId, rect: LayerRect, clip_region: &ClipRegion, start_center: LayerPoint, @@ -618,12 +632,14 @@ impl FrameBuilder { padding: [0.0], }; - self.add_primitive(&rect, + self.add_primitive(scroll_layer_id, + &rect, clip_region, PrimitiveContainer::RadialGradient(radial_gradient_cpu, radial_gradient_gpu)); } pub fn add_text(&mut self, + scroll_layer_id: ScrollLayerId, rect: LayerRect, clip_region: &ClipRegion, font_key: FontKey, @@ -685,13 +701,15 @@ impl FrameBuilder { color: *color, }; - self.add_primitive(&rect, + self.add_primitive(scroll_layer_id, + &rect, clip_region, PrimitiveContainer::TextRun(prim_cpu, prim_gpu)); } } pub fn add_box_shadow(&mut self, + scroll_layer_id: ScrollLayerId, box_bounds: &LayerRect, clip_region: &ClipRegion, box_offset: &LayerPoint, @@ -706,7 +724,8 @@ impl FrameBuilder { // Fast path. if blur_radius == 0.0 && spread_radius == 0.0 && clip_mode == BoxShadowClipMode::None { - self.add_solid_rectangle(&box_bounds, + self.add_solid_rectangle(scroll_layer_id, + &box_bounds, clip_region, color, PrimitiveFlags::None); @@ -782,7 +801,8 @@ impl FrameBuilder { match shadow_kind { BoxShadowKind::Simple(rects) => { for rect in &rects { - self.add_solid_rectangle(rect, + self.add_solid_rectangle(scroll_layer_id, + rect, clip_region, color, PrimitiveFlags::None) @@ -794,6 +814,7 @@ impl FrameBuilder { BoxShadowClipMode::Inset => 1.0, }; + let prim_gpu = BoxShadowPrimitiveGpu { src_rect: *box_bounds, bs_rect: bs_rect, @@ -804,7 +825,8 @@ impl FrameBuilder { inverted: inverted, }; - self.add_primitive(&outer_rect, + self.add_primitive(scroll_layer_id, + &outer_rect, clip_region, PrimitiveContainer::BoxShadow(prim_gpu, rects)); } @@ -812,6 +834,7 @@ impl FrameBuilder { } pub fn add_webgl_rectangle(&mut self, + scroll_layer_id: ScrollLayerId, rect: LayerRect, clip_region: &ClipRegion, context_id: WebGLContextId) { @@ -827,12 +850,14 @@ impl FrameBuilder { tile_spacing: LayerSize::zero(), }; - self.add_primitive(&rect, + self.add_primitive(scroll_layer_id, + &rect, clip_region, PrimitiveContainer::Image(prim_cpu, prim_gpu)); } pub fn add_image(&mut self, + scroll_layer_id: ScrollLayerId, rect: LayerRect, clip_region: &ClipRegion, stretch_size: &LayerSize, @@ -856,12 +881,14 @@ impl FrameBuilder { tile_spacing: *tile_spacing, }; - self.add_primitive(&rect, + self.add_primitive(scroll_layer_id, + &rect, clip_region, PrimitiveContainer::Image(prim_cpu, prim_gpu)); } pub fn add_yuv_image(&mut self, + scroll_layer_id: ScrollLayerId, rect: LayerRect, clip_region: &ClipRegion, y_image_key: ImageKey, @@ -880,7 +907,8 @@ impl FrameBuilder { let prim_gpu = YuvImagePrimitiveGpu::new(rect.size, color_space); - self.add_primitive(&rect, + self.add_primitive(scroll_layer_id, + &rect, clip_region, PrimitiveContainer::YuvImage(prim_cpu, prim_gpu)); } @@ -958,6 +986,7 @@ impl FrameBuilder { let mut sc_stack = Vec::new(); let mut current_task = RenderTask::new_alpha_batch(next_task_index, DeviceIntPoint::zero(), + false, RenderTaskLocation::Fixed); next_task_index.0 += 1; let mut alpha_task_stack = Vec::new(); @@ -974,10 +1003,23 @@ impl FrameBuilder { let stacking_context_rect = &stacking_context.bounding_rect; let composite_count = stacking_context.composite_ops.count(); + + if composite_count == 0 && stacking_context.should_isolate { + let location = RenderTaskLocation::Dynamic(None, stacking_context_rect.size); + let new_task = RenderTask::new_alpha_batch(next_task_index, + stacking_context_rect.origin, + stacking_context.should_isolate, + location); + next_task_index.0 += 1; + let prev_task = mem::replace(&mut current_task, new_task); + alpha_task_stack.push(prev_task); + } + for _ in 0..composite_count { let location = RenderTaskLocation::Dynamic(None, stacking_context_rect.size); let new_task = RenderTask::new_alpha_batch(next_task_index, stacking_context_rect.origin, + stacking_context.should_isolate, location); next_task_index.0 += 1; let prev_task = mem::replace(&mut current_task, new_task); @@ -992,6 +1034,20 @@ impl FrameBuilder { continue; } + let composite_count = stacking_context.composite_ops.count(); + + if composite_count == 0 && stacking_context.should_isolate { + let mut prev_task = alpha_task_stack.pop().unwrap(); + let item = AlphaRenderItem::HardwareComposite(stacking_context_index, + current_task.id, + HardwareCompositeOp::Alpha, + next_z); + next_z += 1; + prev_task.as_alpha_batch().alpha_items.push(item); + prev_task.children.push(current_task); + current_task = prev_task; + } + for filter in &stacking_context.composite_ops.filters { let mut prev_task = alpha_task_stack.pop().unwrap(); let item = AlphaRenderItem::Blend(stacking_context_index, @@ -1004,39 +1060,24 @@ impl FrameBuilder { current_task = prev_task; } if let Some(mix_blend_mode) = stacking_context.composite_ops.mix_blend_mode { - match HardwareCompositeOp::from_mix_blend_mode(mix_blend_mode) { - Some(op) => { - let mut prev_task = alpha_task_stack.pop().unwrap(); - let item = AlphaRenderItem::HardwareComposite(stacking_context_index, - current_task.id, - op, - next_z); - next_z += 1; - prev_task.as_alpha_batch().alpha_items.push(item); - prev_task.children.push(current_task); - current_task = prev_task; - } - None => { - let readback_task = - RenderTask::new_readback(stacking_context_index, - stacking_context.bounding_rect); + let readback_task = + RenderTask::new_readback(stacking_context_index, + stacking_context.bounding_rect); - let mut prev_task = alpha_task_stack.pop().unwrap(); - let item = AlphaRenderItem::Composite(stacking_context_index, - readback_task.id, - current_task.id, - mix_blend_mode, - next_z); - next_z += 1; - prev_task.as_alpha_batch().alpha_items.push(item); - prev_task.children.push(current_task); - prev_task.children.push(readback_task); - current_task = prev_task; - } - } + let mut prev_task = alpha_task_stack.pop().unwrap(); + let item = AlphaRenderItem::Composite(stacking_context_index, + readback_task.id, + current_task.id, + mix_blend_mode, + next_z); + next_z += 1; + prev_task.as_alpha_batch().alpha_items.push(item); + prev_task.children.push(current_task); + prev_task.children.push(readback_task); + current_task = prev_task; } } - PrimitiveRunCmd::PrimitiveRun(first_prim_index, prim_count) => { + PrimitiveRunCmd::PrimitiveRun(first_prim_index, prim_count, scroll_layer_id) => { let stacking_context_index = *sc_stack.last().unwrap(); let stacking_context = &self.stacking_context_store[stacking_context_index.0]; @@ -1045,8 +1086,8 @@ impl FrameBuilder { } let stacking_context_index = *sc_stack.last().unwrap(); - let group_index = - self.stacking_context_store[stacking_context_index.0].clip_scroll_group(); + let group_index = self.stacking_context_store[stacking_context_index.0] + .clip_scroll_group(scroll_layer_id); let clip_scroll_group = &self.clip_scroll_group_store[group_index.0]; for i in 0..prim_count { @@ -1104,10 +1145,8 @@ impl FrameBuilder { let screen_rect = DeviceIntRect::new( DeviceIntPoint::zero(), - DeviceIntSize::from_lengths(device_length(self.screen_rect.size.width as f32, - device_pixel_ratio), - device_length(self.screen_rect.size.height as f32, - device_pixel_ratio))); + DeviceIntSize::new(self.screen_size.width as i32, + self.screen_size.height as i32)); // Pick a size for the cache render targets to be. The main requirement is that it // has to be at least as large as the framebuffer size. This ensures that it will @@ -1173,7 +1212,7 @@ impl FrameBuilder { Frame { device_pixel_ratio: device_pixel_ratio, background_color: self.background_color, - viewport_size: self.screen_rect.size, + window_size: self.screen_size, profile_counters: profile_counters, passes: passes, cache_size: cache_size, @@ -1248,8 +1287,8 @@ impl<'a> LayerRectCalculationAndCullingPass<'a> { self.handle_push_stacking_context(stacking_context_index), &PrimitiveRunCmd::PushScrollLayer(scroll_layer_index) => self.handle_push_scroll_layer(scroll_layer_index), - &PrimitiveRunCmd::PrimitiveRun(prim_index, prim_count) => - self.handle_primitive_run(prim_index, prim_count), + &PrimitiveRunCmd::PrimitiveRun(prim_index, prim_count, scroll_layer_id) => + self.handle_primitive_run(prim_index, prim_count, scroll_layer_id), &PrimitiveRunCmd::PopStackingContext => self.handle_pop_stacking_context(), &PrimitiveRunCmd::PopScrollLayer => self.handle_pop_scroll_layer(), } @@ -1264,45 +1303,41 @@ impl<'a> LayerRectCalculationAndCullingPass<'a> { let stacking_context = &mut self.frame_builder .stacking_context_store[stacking_context_index.0]; - let scroll_tree_layer = &self.clip_scroll_tree.nodes[&group.scroll_layer_id]; + let node = &self.clip_scroll_tree.nodes[&group.scroll_layer_id]; let packed_layer = &mut self.frame_builder.packed_layers[group.packed_layer_index.0]; - packed_layer.transform = scroll_tree_layer.world_content_transform - .with_source::() - .pre_mul(&stacking_context.local_transform); - packed_layer.inv_transform = packed_layer.transform.inverse().unwrap(); + + // The world content transform is relative to the containing reference frame, + // so we translate into the origin of the stacking context itself. + let transform = node.world_content_transform + .pre_translated(stacking_context.reference_frame_offset.x, + stacking_context.reference_frame_offset.y, + 0.0); + packed_layer.set_transform(transform); if !stacking_context.can_contribute_to_scene() { return; } - let inv_layer_transform = stacking_context.local_transform.inverse().unwrap(); - let local_viewport_rect = - as_scroll_parent_rect(&scroll_tree_layer.combined_local_viewport_rect); - let viewport_rect = inv_layer_transform.transform_rect(&local_viewport_rect); - let layer_local_rect = stacking_context.local_rect.intersection(&viewport_rect); + // Here we want to find the intersection between the clipping region and the + // stacking context content, so we move the viewport rectangle into the coordinate + // system of the stacking context content. + let viewport_rect = + &node.combined_local_viewport_rect + .translate(&-stacking_context.reference_frame_offset) + .translate(&-node.scrolling.offset); + let intersected_rect = stacking_context.local_rect.intersection(viewport_rect); - group.xf_rect = None; - - let layer_local_rect = match layer_local_rect { - Some(layer_local_rect) if !layer_local_rect.is_empty() => layer_local_rect, - _ => continue, - }; - - let layer_xf_rect = TransformedRect::new(&layer_local_rect, - &packed_layer.transform, - self.device_pixel_ratio); - - if layer_xf_rect.bounding_rect.intersects(&self.screen_rect) { - packed_layer.screen_vertices = layer_xf_rect.vertices.clone(); - packed_layer.local_clip_rect = layer_local_rect; - group.xf_rect = Some(layer_xf_rect); - } + group.xf_rect = packed_layer.set_rect(intersected_rect, + self.screen_rect, + self.device_pixel_ratio); } } fn compute_stacking_context_visibility(&mut self) { for context_index in 0..self.frame_builder.stacking_context_store.len() { let is_visible = { + // We don't take into account visibility of children here, so we must + // do that later. let stacking_context = &self.frame_builder.stacking_context_store[context_index]; stacking_context.clip_scroll_groups.iter().any(|group_index| { self.frame_builder.clip_scroll_group_store[group_index.0].is_visible() @@ -1315,18 +1350,22 @@ impl<'a> LayerRectCalculationAndCullingPass<'a> { fn handle_pop_stacking_context(&mut self) { let stacking_context_index = self.stacking_context_stack.pop().unwrap(); - let bounding_rect = { + let (bounding_rect, is_visible) = { let stacking_context = &mut self.frame_builder.stacking_context_store[stacking_context_index.0]; stacking_context.bounding_rect = stacking_context.bounding_rect .intersection(self.screen_rect) .unwrap_or(DeviceIntRect::zero()); - stacking_context.bounding_rect.clone() + (stacking_context.bounding_rect.clone(), stacking_context.is_visible) }; if let Some(ref mut parent_index) = self.stacking_context_stack.last_mut() { let parent = &mut self.frame_builder.stacking_context_store[parent_index.0]; parent.bounding_rect = parent.bounding_rect.union(&bounding_rect); + + // The previous compute_stacking_context_visibility pass did not take into + // account visibility of children, so we do that now. + parent.is_visible = parent.is_visible || is_visible; } } @@ -1334,27 +1373,29 @@ impl<'a> LayerRectCalculationAndCullingPass<'a> { self.scroll_layer_stack.push(scroll_layer_index); let scroll_layer = &mut self.frame_builder.scroll_layer_store[scroll_layer_index.0]; + let node = &self.clip_scroll_tree.nodes[&scroll_layer.scroll_layer_id]; + let packed_layer_index = scroll_layer.packed_layer_index; - let scroll_tree_layer = &self.clip_scroll_tree.nodes[&scroll_layer.scroll_layer_id]; let packed_layer = &mut self.frame_builder.packed_layers[packed_layer_index.0]; - packed_layer.transform = scroll_tree_layer.world_viewport_transform; - packed_layer.inv_transform = packed_layer.transform.inverse().unwrap(); + // The coordinates of the mask are relative to the origin of the node itself, + // so we need to account for that origin in the transformation we assign to + // the packed layer. + let transform = node.world_viewport_transform + .pre_translated(node.local_viewport_rect.origin.x, + node.local_viewport_rect.origin.y, + 0.0); + packed_layer.set_transform(transform); - let local_rect = &scroll_tree_layer.combined_local_viewport_rect - .translate(&scroll_tree_layer.scrolling.offset); - if !local_rect.is_empty() { - let layer_xf_rect = TransformedRect::new(local_rect, - &packed_layer.transform, + // Meanwhile, the combined viewport rect is relative to the reference frame, so + // we move it into the local coordinate system of the node. + let local_viewport_rect = + node.combined_local_viewport_rect.translate(&-node.local_viewport_rect.origin); + + scroll_layer.xf_rect = packed_layer.set_rect(Some(local_viewport_rect), + self.screen_rect, self.device_pixel_ratio); - if layer_xf_rect.bounding_rect.intersects(&self.screen_rect) { - packed_layer.screen_vertices = layer_xf_rect.vertices.clone(); - packed_layer.local_clip_rect = *local_rect; - scroll_layer.xf_rect = Some(layer_xf_rect); - } - } - let clip_info = match scroll_layer.clip_cache_info { Some(ref mut clip_info) => clip_info, None => return, @@ -1417,7 +1458,10 @@ impl<'a> LayerRectCalculationAndCullingPass<'a> { self.current_clip_stack.reverse(); } - fn handle_primitive_run(&mut self, prim_index: PrimitiveIndex, prim_count: usize) { + fn handle_primitive_run(&mut self, + prim_index: PrimitiveIndex, + prim_count: usize, + scroll_layer_id: ScrollLayerId) { let stacking_context_index = *self.stacking_context_stack.last().unwrap(); let (packed_layer_index, pipeline_id) = { let stacking_context = @@ -1427,7 +1471,7 @@ impl<'a> LayerRectCalculationAndCullingPass<'a> { return; } - let group_index = stacking_context.clip_scroll_group(); + let group_index = stacking_context.clip_scroll_group(scroll_layer_id); let clip_scroll_group = &self.frame_builder.clip_scroll_group_store[group_index.0]; (clip_scroll_group.packed_layer_index, stacking_context.pipeline_id) }; diff --git a/gfx/webrender/src/internal_types.rs b/gfx/webrender/src/internal_types.rs index bc6c11ec65b7..ef1ade7e1d6a 100644 --- a/gfx/webrender/src/internal_types.rs +++ b/gfx/webrender/src/internal_types.rs @@ -20,7 +20,7 @@ use std::sync::Arc; use tiling; use renderer::BlendMode; use webrender_traits::{Epoch, ColorF, PipelineId, DeviceIntSize}; -use webrender_traits::{ImageFormat, NativeFontHandle, MixBlendMode}; +use webrender_traits::{ImageFormat, NativeFontHandle}; use webrender_traits::{ExternalImageId, ScrollLayerId, WebGLCommand}; use webrender_traits::{ImageData}; use webrender_traits::{DeviceUintRect}; @@ -492,26 +492,13 @@ pub enum LowLevelFilterOp { #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] pub enum HardwareCompositeOp { - Multiply, - Max, - Min, + Alpha, } impl HardwareCompositeOp { - pub fn from_mix_blend_mode(mix_blend_mode: MixBlendMode) -> Option { - match mix_blend_mode { - MixBlendMode::Multiply => Some(HardwareCompositeOp::Multiply), - MixBlendMode::Lighten => Some(HardwareCompositeOp::Max), - MixBlendMode::Darken => Some(HardwareCompositeOp::Min), - _ => None, - } - } - pub fn to_blend_mode(&self) -> BlendMode { match self { - &HardwareCompositeOp::Multiply => BlendMode::Multiply, - &HardwareCompositeOp::Max => BlendMode::Max, - &HardwareCompositeOp::Min => BlendMode::Min, + &HardwareCompositeOp::Alpha => BlendMode::Alpha, } } } diff --git a/gfx/webrender/src/platform/macos/font.rs b/gfx/webrender/src/platform/macos/font.rs index 2cfeed338a64..ed9f7e6c6179 100644 --- a/gfx/webrender/src/platform/macos/font.rs +++ b/gfx/webrender/src/platform/macos/font.rs @@ -147,6 +147,18 @@ impl FontContext { self.cg_fonts.insert((*font_key).clone(), native_font_handle); } + pub fn delete_font(&mut self, font_key: &FontKey) { + if let Some(cg_font) = self.cg_fonts.remove(font_key) { + let ct_font_keys = self.ct_fonts.keys() + .filter(|k| k.0 == *font_key) + .cloned() + .collect::>(); + for ct_font_key in ct_font_keys { + self.ct_fonts.remove(&ct_font_key); + } + } + } + fn get_ct_font(&mut self, font_key: FontKey, size: Au) -> Option { diff --git a/gfx/webrender/src/platform/unix/font.rs b/gfx/webrender/src/platform/unix/font.rs index 0058bad7083f..f4c42006effc 100644 --- a/gfx/webrender/src/platform/unix/font.rs +++ b/gfx/webrender/src/platform/unix/font.rs @@ -13,6 +13,7 @@ use freetype::freetype::{FT_Library, FT_Set_Char_Size}; use freetype::freetype::{FT_Face, FT_Long, FT_UInt, FT_F26Dot6}; use freetype::freetype::{FT_Init_FreeType, FT_Load_Glyph, FT_Render_Glyph}; use freetype::freetype::{FT_New_Memory_Face, FT_GlyphSlot, FT_LcdFilter}; +use freetype::freetype::{FT_Done_Face}; use std::{mem, ptr, slice}; use std::collections::HashMap; @@ -88,6 +89,15 @@ impl FontContext { panic!("TODO: Not supported on Linux"); } + pub fn delete_font(&mut self, font_key: &FontKey) { + if let Some(face) = self.faces.remove(font_key) { + let result = unsafe { + FT_Done_Face(face.face) + }; + assert!(result.succeeded()); + } + } + fn load_glyph(&self, font_key: FontKey, size: Au, diff --git a/gfx/webrender/src/platform/windows/font.rs b/gfx/webrender/src/platform/windows/font.rs index 640cc96f7ac0..c0bf0b1af0a8 100644 --- a/gfx/webrender/src/platform/windows/font.rs +++ b/gfx/webrender/src/platform/windows/font.rs @@ -143,6 +143,10 @@ impl FontContext { self.fonts.insert((*font_key).clone(), face); } + pub fn delete_font(&mut self, font_key: &FontKey) { + self.fonts.remove(font_key); + } + // Assumes RGB format from dwrite, which is 3 bytes per pixel as dwrite // doesn't output an alpha value via GlyphRunAnalysis::CreateAlphaTexture #[allow(dead_code)] @@ -230,13 +234,8 @@ impl FontContext { let length = pixels.len() / 3; let mut rgba_pixels: Vec = vec![0; length * 4]; for i in 0..length { - // TODO(vlad): we likely need to do something smarter - // This is what skia does - let alpha = ((pixels[i*3+0] as u32 + - pixels[i*3+1] as u32 + - pixels[i*3+2] as u32) - / 3) as u8; - + // Only take the G channel, as its closest to D2D + let alpha = pixels[i*3 + 1] as u8; rgba_pixels[i*4+0] = alpha; rgba_pixels[i*4+1] = alpha; rgba_pixels[i*4+2] = alpha; @@ -278,22 +277,24 @@ impl FontContext { let mut pixels = analysis.create_alpha_texture(texture_type, bounds); - let lut_correction = match glyph_options { - Some(option) => { - if option.force_gdi_rendering { - &self.gdi_gamma_lut - } else { - &self.gamma_lut - } - }, - None => &self.gamma_lut - }; + if render_mode != FontRenderMode::Mono { + let lut_correction = match glyph_options { + Some(option) => { + if option.force_gdi_rendering { + &self.gdi_gamma_lut + } else { + &self.gamma_lut + } + }, + None => &self.gamma_lut + }; - lut_correction.preblend_rgb(&mut pixels, width, height, - ColorLut::new(key.color.r, - key.color.g, - key.color.b, - key.color.a)); + lut_correction.preblend_rgb(&mut pixels, width, height, + ColorLut::new(key.color.r, + key.color.g, + key.color.b, + key.color.a)); + } let rgba_pixels = self.convert_to_rgba(&mut pixels, render_mode); diff --git a/gfx/webrender/src/record.rs b/gfx/webrender/src/record.rs index d0b7c9b4e9e0..574201d226a7 100644 --- a/gfx/webrender/src/record.rs +++ b/gfx/webrender/src/record.rs @@ -66,6 +66,7 @@ pub fn should_record_msg(msg: &ApiMsg) -> bool { match msg { &ApiMsg::AddRawFont(..) | &ApiMsg::AddNativeFont(..) | + &ApiMsg::DeleteFont(..) | &ApiMsg::AddImage(..) | &ApiMsg::GenerateFrame(..) | &ApiMsg::UpdateImage(..) | diff --git a/gfx/webrender/src/render_backend.rs b/gfx/webrender/src/render_backend.rs index eeb0a5d8bbd9..fed13ed80884 100644 --- a/gfx/webrender/src/render_backend.rs +++ b/gfx/webrender/src/render_backend.rs @@ -18,6 +18,7 @@ use std::sync::mpsc::Sender; use texture_cache::TextureCache; use thread_profiler::register_thread_with_profiler; use threadpool::ThreadPool; +use webrender_traits::{DeviceUintPoint, DeviceUintRect, DeviceUintSize}; use webrender_traits::{ApiMsg, AuxiliaryLists, BuiltDisplayList, IdNamespace, ImageData}; use webrender_traits::{PipelineId, RenderNotifier, RenderDispatcher, WebGLCommand, WebGLContextId}; use webrender_traits::channel::{PayloadHelperMethods, PayloadReceiver, PayloadSender, MsgReceiver}; @@ -35,6 +36,9 @@ pub struct RenderBackend { result_tx: Sender, device_pixel_ratio: f32, + page_zoom_factor: f32, + window_size: DeviceUintSize, + inner_rect: DeviceUintRect, next_namespace_id: IdNamespace, resource_cache: ResourceCache, @@ -69,7 +73,8 @@ impl RenderBackend { recorder: Option>, main_thread_dispatcher: Arc>>>, blob_image_renderer: Option>, - vr_compositor_handler: Arc>>>) -> RenderBackend { + vr_compositor_handler: Arc>>>, + initial_window_size: DeviceUintSize) -> RenderBackend { let resource_cache = ResourceCache::new(texture_cache, workers, blob_image_renderer, enable_aa); @@ -81,6 +86,7 @@ impl RenderBackend { payload_tx: payload_tx, result_tx: result_tx, device_pixel_ratio: device_pixel_ratio, + page_zoom_factor: 1.0, resource_cache: resource_cache, scene: Scene::new(), frame: Frame::new(config), @@ -92,7 +98,9 @@ impl RenderBackend { recorder: recorder, main_thread_dispatcher: main_thread_dispatcher, next_webgl_id: 0, - vr_compositor_handler: vr_compositor_handler + vr_compositor_handler: vr_compositor_handler, + window_size: initial_window_size, + inner_rect: DeviceUintRect::new(DeviceUintPoint::zero(), initial_window_size), } } @@ -117,6 +125,9 @@ impl RenderBackend { self.resource_cache .add_font_template(id, FontTemplate::Native(native_font_handle)); } + ApiMsg::DeleteFont(id) => { + self.resource_cache.delete_font_template(id); + } ApiMsg::GetGlyphDimensions(glyph_keys, tx) => { let mut glyph_dimensions = Vec::with_capacity(glyph_keys.len()); for glyph_key in &glyph_keys { @@ -137,6 +148,13 @@ impl RenderBackend { ApiMsg::DeleteImage(id) => { self.resource_cache.delete_image_template(id); } + ApiMsg::SetPageZoom(factor) => { + self.page_zoom_factor = factor.get(); + } + ApiMsg::SetWindowParameters(window_size, inner_rect) => { + self.window_size = window_size; + self.inner_rect = inner_rect; + } ApiMsg::CloneApi(sender) => { let result = self.next_namespace_id; @@ -418,17 +436,23 @@ impl RenderBackend { webgl_context.unbind(); } - self.frame.create(&self.scene, &mut self.resource_cache); + let device_pixel_ratio = self.device_pixel_ratio * self.page_zoom_factor; + + self.frame.create(&self.scene, + &mut self.resource_cache, + self.window_size, + self.inner_rect, + device_pixel_ratio); } fn render(&mut self, texture_cache_profile: &mut TextureCacheProfileCounters) -> RendererFrame { + let device_pixel_ratio = self.device_pixel_ratio * self.page_zoom_factor; let frame = self.frame.build(&mut self.resource_cache, &self.scene.pipeline_auxiliary_lists, - self.device_pixel_ratio, + device_pixel_ratio, texture_cache_profile); - frame } diff --git a/gfx/webrender/src/render_task.rs b/gfx/webrender/src/render_task.rs index adf21edffa67..de5ab1671aa3 100644 --- a/gfx/webrender/src/render_task.rs +++ b/gfx/webrender/src/render_task.rs @@ -62,6 +62,7 @@ pub struct AlphaRenderTask { screen_origin: DeviceIntPoint, pub opaque_items: Vec, pub alpha_items: Vec, + pub isolate_clear: bool, } #[derive(Debug, Copy, Clone)] @@ -144,6 +145,7 @@ pub struct RenderTask { impl RenderTask { pub fn new_alpha_batch(task_index: RenderTaskIndex, screen_origin: DeviceIntPoint, + isolate_clear: bool, location: RenderTaskLocation) -> RenderTask { RenderTask { id: RenderTaskId::Static(task_index), @@ -153,6 +155,7 @@ impl RenderTask { screen_origin: screen_origin, alpha_items: Vec::new(), opaque_items: Vec::new(), + isolate_clear: isolate_clear, }), } } diff --git a/gfx/webrender/src/renderer.rs b/gfx/webrender/src/renderer.rs index 4095cb4b4710..05ecad61c189 100644 --- a/gfx/webrender/src/renderer.rs +++ b/gfx/webrender/src/renderer.rs @@ -80,10 +80,6 @@ pub enum BlendMode { None, Alpha, - Multiply, - Max, - Min, - // Use the color of the text itself as a constant color blend factor. Subpixel(ColorF), } @@ -513,7 +509,8 @@ impl Renderer { /// }; /// let (renderer, sender) = Renderer::new(opts); /// ``` - pub fn new(mut options: RendererOptions) -> Result<(Renderer, RenderApiSender), InitError> { + pub fn new(mut options: RendererOptions, + initial_window_size: DeviceUintSize) -> Result<(Renderer, RenderApiSender), InitError> { let (api_tx, api_rx) = try!{ channel::msg_channel() }; let (payload_tx, payload_rx) = try!{ channel::payload_channel() }; let (result_tx, result_rx) = channel(); @@ -805,7 +802,8 @@ impl Renderer { recorder, backend_main_thread_dispatcher, blob_image_renderer, - backend_vr_compositor); + backend_vr_compositor, + initial_window_size); backend.run(backend_profile_counters); })}; @@ -1206,7 +1204,6 @@ impl Renderer { let shader = match batch.key.blend_mode { BlendMode::Subpixel(..) => self.ps_text_run_subpixel.get(&mut self.device, transform_kind), BlendMode::Alpha | BlendMode::None => self.ps_text_run.get(&mut self.device, transform_kind), - _ => unreachable!(), }; (GPU_TAG_PRIM_TEXT_RUN, shader) } @@ -1290,20 +1287,18 @@ impl Renderer { let width = readback.data[2]; let height = readback.data[3]; - // Need to invert the y coordinates when reading back from - // the framebuffer. - let y0 = if render_target.is_some() { - src_y as i32 - } else { - target_dimensions.height as i32 - height as i32 - src_y as i32 - }; + let mut src = DeviceIntRect::new(DeviceIntPoint::new(src_x as i32, src_y as i32), + DeviceIntSize::new(width as i32, height as i32)); + let mut dest = DeviceIntRect::new(DeviceIntPoint::new(dest_x as i32, dest_y as i32), + DeviceIntSize::new(width as i32, height as i32)); - let src = DeviceIntRect::new(DeviceIntPoint::new(src_x as i32, - y0), - DeviceIntSize::new(width as i32, height as i32)); - let dest = DeviceIntRect::new(DeviceIntPoint::new(dest_x as i32, - dest_y as i32), - DeviceIntSize::new(width as i32, height as i32)); + // Need to invert the y coordinates and flip the image vertically when + // reading back from the framebuffer. + if render_target.is_none() { + src.origin.y = target_dimensions.height as i32 - src.size.height - src.origin.y; + dest.origin.y += dest.size.height; + dest.size.height = -dest.size.height; + } self.device.blit_render_target(render_target, Some(src), @@ -1381,6 +1376,11 @@ impl Renderer { self.device.clear_target(clear_color, clear_depth); + let isolate_clear_color = Some([0.0, 0.0, 0.0, 0.0]); + for isolate_clear in &target.isolate_clears { + self.device.clear_target_rect(isolate_clear_color, None, *isolate_clear); + } + projection }; @@ -1501,18 +1501,6 @@ impl Renderer { BlendMode::None => { self.device.set_blend(false); } - BlendMode::Multiply => { - self.device.set_blend(true); - self.device.set_blend_mode_multiply(); - } - BlendMode::Max => { - self.device.set_blend(true); - self.device.set_blend_mode_max(); - } - BlendMode::Min => { - self.device.set_blend(true); - self.device.set_blend_mode_min(); - } BlendMode::Alpha => { self.device.set_blend(true); self.device.set_blend_mode_alpha(); @@ -1601,10 +1589,8 @@ impl Renderer { // Some tests use a restricted viewport smaller than the main screen size. // Ensure we clear the framebuffer in these tests. // TODO(gw): Find a better solution for this? - let viewport_size = DeviceIntSize::new((frame.viewport_size.width * frame.device_pixel_ratio) as i32, - (frame.viewport_size.height * frame.device_pixel_ratio) as i32); - let needs_clear = viewport_size.width < framebuffer_size.width as i32 || - viewport_size.height < framebuffer_size.height as i32; + let needs_clear = frame.window_size.width < framebuffer_size.width || + frame.window_size.height < framebuffer_size.height; self.device.disable_depth_write(); self.device.disable_stencil(); diff --git a/gfx/webrender/src/resource_cache.rs b/gfx/webrender/src/resource_cache.rs index 8dd1ee12b021..af4d0b50bba1 100644 --- a/gfx/webrender/src/resource_cache.rs +++ b/gfx/webrender/src/resource_cache.rs @@ -41,6 +41,8 @@ enum GlyphCacheMsg { AddFont(FontKey, FontTemplate), /// Request glyphs for a text run. RequestGlyphs(FontKey, Au, ColorF, Vec, FontRenderMode, Option), + // Remove an existing font. + DeleteFont(FontKey), /// Finished requesting glyphs. Reply with new glyphs. EndFrame, } @@ -260,6 +262,13 @@ impl ResourceCache { self.font_templates.insert(font_key, template); } + pub fn delete_font_template(&mut self, font_key: FontKey) { + self.glyph_cache_tx + .send(GlyphCacheMsg::DeleteFont(font_key)) + .unwrap(); + self.font_templates.remove(&font_key); + } + pub fn add_image_template(&mut self, image_key: ImageKey, descriptor: ImageDescriptor, @@ -839,6 +848,23 @@ fn spawn_glyph_cache_thread(workers: Arc>) -> (Sender { + profile_scope!("DeleteFont"); + + // Delete a font from the font context in each worker thread. + let barrier = Arc::new(Barrier::new(worker_count)); + for _ in 0..worker_count { + let barrier = barrier.clone(); + workers.lock().unwrap().execute(move || { + FONT_CONTEXT.with(|font_context| { + let mut font_context = font_context.borrow_mut(); + font_context.delete_font(&font_key); + }); + barrier.wait(); + }); + } + + } GlyphCacheMsg::RequestGlyphs(key, size, color, glyph_instances, render_mode, glyph_options) => { profile_scope!("RequestGlyphs"); diff --git a/gfx/webrender/src/scene.rs b/gfx/webrender/src/scene.rs index 518e4093a902..d8fe60d5ff98 100644 --- a/gfx/webrender/src/scene.rs +++ b/gfx/webrender/src/scene.rs @@ -41,7 +41,14 @@ impl SceneProperties { } /// Get the current value for a transform property. - pub fn resolve_layout_transform(&self, property: &PropertyBinding) -> LayoutTransform { + pub fn resolve_layout_transform(&self, + property: Option<&PropertyBinding>) + -> LayoutTransform { + let property = match property { + Some(property) => property, + None => return LayoutTransform::identity(), + }; + match *property { PropertyBinding::Value(matrix) => matrix, PropertyBinding::Binding(ref key) => { diff --git a/gfx/webrender/src/tiling.rs b/gfx/webrender/src/tiling.rs index 51cdf16331cd..4347b7961827 100644 --- a/gfx/webrender/src/tiling.rs +++ b/gfx/webrender/src/tiling.rs @@ -23,9 +23,9 @@ use std::hash::BuildHasherDefault; use texture_cache::TexturePage; use util::{TransformedRect, TransformedRectKind}; use webrender_traits::{AuxiliaryLists, ColorF, DeviceIntPoint, DeviceIntRect, DeviceUintPoint}; -use webrender_traits::{DeviceUintSize, FontRenderMode, ImageRendering, LayerRect, LayerSize}; -use webrender_traits::{LayerToScrollTransform, LayerToWorldTransform, MixBlendMode, PipelineId}; -use webrender_traits::{ScrollLayerId, WorldPoint4D, WorldToLayerTransform}; +use webrender_traits::{DeviceUintSize, FontRenderMode, ImageRendering, LayerPoint, LayerRect}; +use webrender_traits::{LayerToWorldTransform, MixBlendMode, PipelineId, ScrollLayerId}; +use webrender_traits::{WorldPoint4D, WorldToLayerTransform}; // Special sentinel value recognized by the shader. It is considered to be // a dummy task that doesn't mask out anything. @@ -398,7 +398,7 @@ pub enum PrimitiveRunCmd { PushScrollLayer(ScrollLayerIndex), PopScrollLayer, - PrimitiveRun(PrimitiveIndex, usize), + PrimitiveRun(PrimitiveIndex, usize, ScrollLayerId), } #[derive(Debug, Copy, Clone)] @@ -870,6 +870,7 @@ pub struct RenderTarget { pub vertical_blurs: Vec, pub horizontal_blurs: Vec, pub readbacks: Vec, + pub isolate_clears: Vec, page_allocator: TexturePage, } @@ -884,6 +885,7 @@ impl RenderTarget { vertical_blurs: Vec::new(), horizontal_blurs: Vec::new(), readbacks: Vec::new(), + isolate_clears: Vec::new(), page_allocator: TexturePage::new(CacheTextureId(0), size), } } @@ -909,6 +911,16 @@ impl RenderTarget { opaque_items: info.opaque_items, alpha_items: info.alpha_items, }); + + if info.isolate_clear { + let location = match task.location { + RenderTaskLocation::Dynamic(origin, size) => { + DeviceIntRect::new(origin.unwrap().0, size) + } + RenderTaskLocation::Fixed => panic!() + }; + self.isolate_clears.push(location); + } } RenderTaskKind::VerticalBlur(_, prim_index) => { // Find the child render task that we are applying @@ -1301,53 +1313,79 @@ pub struct StackingContextIndex(pub usize); #[derive(Debug)] pub struct StackingContext { pub pipeline_id: PipelineId, - pub local_transform: LayerToScrollTransform, + + // Offset in the parent reference frame to the origin of this stacking + // context's coordinate system. + pub reference_frame_offset: LayerPoint, + + // Bounds of this stacking context in its own coordinate system. pub local_rect: LayerRect, + pub bounding_rect: DeviceIntRect, pub composite_ops: CompositeOps, pub clip_scroll_groups: Vec, + + // Signifies that this stacking context should be drawn in a separate render pass + // with a transparent background and then composited back to its parent. Used to + // support mix-blend-mode in certain cases. + pub should_isolate: bool, + + // Set for the root stacking context of a display list or an iframe. Used for determining + // when to isolate a mix-blend-mode composite. + pub is_page_root: bool, + pub is_visible: bool, } impl StackingContext { pub fn new(pipeline_id: PipelineId, - local_transform: LayerToScrollTransform, + reference_frame_offset: LayerPoint, local_rect: LayerRect, - composite_ops: CompositeOps, - clip_scroll_group_index: ClipScrollGroupIndex) + is_page_root: bool, + composite_ops: CompositeOps) -> StackingContext { StackingContext { pipeline_id: pipeline_id, - local_transform: local_transform, + reference_frame_offset: reference_frame_offset, local_rect: local_rect, bounding_rect: DeviceIntRect::zero(), composite_ops: composite_ops, - clip_scroll_groups: vec![clip_scroll_group_index], + clip_scroll_groups: Vec::new(), + should_isolate: false, + is_page_root: is_page_root, is_visible: false, } } - pub fn clip_scroll_group(&self) -> ClipScrollGroupIndex { + pub fn clip_scroll_group(&self, scroll_layer_id: ScrollLayerId) -> ClipScrollGroupIndex { // Currently there is only one scrolled stacking context per context, // but eventually this will be selected from the vector based on the // scroll layer of this primitive. - self.clip_scroll_groups[0] + for group in &self.clip_scroll_groups { + if group.1 == scroll_layer_id { + return *group; + } + } + unreachable!("Looking for non-existent ClipScrollGroup"); } pub fn can_contribute_to_scene(&self) -> bool { !self.composite_ops.will_make_invisible() } + + pub fn has_clip_scroll_group(&self, id: ScrollLayerId) -> bool { + self.clip_scroll_groups.iter().rev().any(|index| index.1 == id) + } } -#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash, Ord, PartialOrd)] -pub struct ClipScrollGroupIndex(pub usize); +#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] +pub struct ClipScrollGroupIndex(pub usize, pub ScrollLayerId); #[derive(Debug)] pub struct ClipScrollGroup { pub stacking_context_index: StackingContextIndex, pub scroll_layer_id: ScrollLayerId, pub packed_layer_index: PackedLayerIndex, - pub pipeline_id: PipelineId, pub xf_rect: Option, } @@ -1393,6 +1431,31 @@ impl PackedLayer { pub fn empty() -> PackedLayer { Default::default() } + + pub fn set_transform(&mut self, transform: LayerToWorldTransform) { + self.transform = transform; + self.inv_transform = self.transform.inverse().unwrap(); + } + + pub fn set_rect(&mut self, + local_rect: Option, + screen_rect: &DeviceIntRect, + device_pixel_ratio: f32) + -> Option { + let local_rect = match local_rect { + Some(rect) if !rect.is_empty() => rect, + _ => return None, + }; + + let xf_rect = TransformedRect::new(&local_rect, &self.transform, device_pixel_ratio); + if !xf_rect.bounding_rect.intersects(screen_rect) { + return None; + } + + self.screen_vertices = xf_rect.vertices.clone(); + self.local_clip_rect = local_rect; + Some(xf_rect) + } } #[derive(Debug, Clone)] @@ -1437,7 +1500,7 @@ impl CompositeOps { /// A rendering-oriented representation of frame::Frame built by the render backend /// and presented to the renderer. pub struct Frame { - pub viewport_size: LayerSize, + pub window_size: DeviceUintSize, pub background_color: Option, pub device_pixel_ratio: f32, pub cache_size: DeviceUintSize, diff --git a/gfx/webrender_bindings/Cargo.toml b/gfx/webrender_bindings/Cargo.toml index 819fa6edf99c..2139a4d7aa03 100644 --- a/gfx/webrender_bindings/Cargo.toml +++ b/gfx/webrender_bindings/Cargo.toml @@ -5,13 +5,12 @@ authors = ["The Mozilla Project Developers"] license = "MPL-2.0" [dependencies] -webrender_traits = {path = "../webrender_traits", version = "0.20.0"} +webrender_traits = {path = "../webrender_traits", version = "0.23.1"} euclid = "0.11" app_units = "0.4" gleam = "0.2" [dependencies.webrender] path = "../webrender" -version = "0.19.0" +version = "0.22.1" default-features = false -features = ["codegen"] diff --git a/gfx/webrender_bindings/WebRenderAPI.cpp b/gfx/webrender_bindings/WebRenderAPI.cpp index abdc179a9726..a0770c51baf2 100644 --- a/gfx/webrender_bindings/WebRenderAPI.cpp +++ b/gfx/webrender_bindings/WebRenderAPI.cpp @@ -21,7 +21,8 @@ public: bool* aUseANGLE, RefPtr&& aWidget, layers::SynchronousTask* aTask, - bool aEnableProfiler) + bool aEnableProfiler, + LayoutDeviceIntSize aSize) : mWrApi(aApi) , mMaxTextureSize(aMaxTextureSize) , mUseANGLE(aUseANGLE) @@ -29,6 +30,7 @@ public: , mCompositorWidget(Move(aWidget)) , mTask(aTask) , mEnableProfiler(aEnableProfiler) + , mSize(aSize) { MOZ_COUNT_CTOR(NewRenderer); } @@ -51,7 +53,8 @@ public: *mUseANGLE = gl->IsANGLE(); WrRenderer* wrRenderer = nullptr; - if (!wr_window_new(aWindowId, gl.get(), this->mEnableProfiler, mWrApi, &wrRenderer)) { + if (!wr_window_new(aWindowId, mSize.width, mSize.height, gl.get(), + this->mEnableProfiler, mWrApi, &wrRenderer)) { return; } MOZ_ASSERT(wrRenderer); @@ -79,6 +82,7 @@ private: RefPtr mCompositorWidget; layers::SynchronousTask* mTask; bool mEnableProfiler; + LayoutDeviceIntSize mSize; }; class RemoveRenderer : public RendererEvent @@ -110,7 +114,8 @@ private: already_AddRefed WebRenderAPI::Create(bool aEnableProfiler, layers::CompositorBridgeParentBase* aBridge, - RefPtr&& aWidget) + RefPtr&& aWidget, + LayoutDeviceIntSize aSize) { MOZ_ASSERT(aBridge); MOZ_ASSERT(aWidget); @@ -127,7 +132,7 @@ WebRenderAPI::Create(bool aEnableProfiler, // the next time we need to access the WrApi object. layers::SynchronousTask task("Create Renderer"); auto event = MakeUnique(&wrApi, aBridge, &maxTextureSize, &useANGLE, - Move(aWidget), &task, aEnableProfiler); + Move(aWidget), &task, aEnableProfiler, aSize); RenderThread::Get()->RunEvent(id, Move(event)); task.Wait(); diff --git a/gfx/webrender_bindings/WebRenderAPI.h b/gfx/webrender_bindings/WebRenderAPI.h index 9b97410ad3f8..8a20bdd6b33a 100644 --- a/gfx/webrender_bindings/WebRenderAPI.h +++ b/gfx/webrender_bindings/WebRenderAPI.h @@ -39,7 +39,8 @@ public: /// This can be called on the compositor thread only. static already_AddRefed Create(bool aEnableProfiler, layers::CompositorBridgeParentBase* aBridge, - RefPtr&& aWidget); + RefPtr&& aWidget, + LayoutDeviceIntSize aSize); wr::WindowId GetId() const { return mId; } diff --git a/gfx/webrender_bindings/src/bindings.rs b/gfx/webrender_bindings/src/bindings.rs index 59cad0f6219d..b69f031b86f6 100644 --- a/gfx/webrender_bindings/src/bindings.rs +++ b/gfx/webrender_bindings/src/bindings.rs @@ -282,6 +282,8 @@ pub extern fn wr_api_generate_frame(api: &mut RenderApi) { // Call MakeCurrent before this. #[no_mangle] pub extern fn wr_window_new(window_id: WrWindowId, + window_width: u32, + window_height: u32, gl_context: *mut c_void, enable_profiler: bool, out_api: &mut *mut RenderApi, @@ -310,7 +312,8 @@ pub extern fn wr_window_new(window_id: WrWindowId, .. Default::default() }; - let (renderer, sender) = match Renderer::new(opts) { + let window_size = DeviceUintSize::new(window_width, window_height); + let (renderer, sender) = match Renderer::new(opts, window_size) { Ok((renderer, sender)) => { (renderer, sender) } Err(e) => { println!(" Failed to create a Renderer: {:?}", e); @@ -361,8 +364,8 @@ pub extern fn wr_dp_begin(state: &mut WrState, width: u32, height: u32) { bounds, ClipRegion::simple(&bounds), 0, - PropertyBinding::Value(LayoutTransform::identity()), - LayoutTransform::identity(), + None, + None, webrender_traits::MixBlendMode::Normal, Vec::new(), ); @@ -637,8 +640,8 @@ pub extern fn wr_dp_push_stacking_context(state:&mut WrState, bounds: WrRect, ov bounds, clip_region2, state.z_index, - PropertyBinding::Value(*transform), - LayoutTransform::identity(), + Some(PropertyBinding::Value(*transform)), + None, mix_blend_mode, filters); state.frame_builder.dl_builder.push_scroll_layer(clip_region, bounds.size, ServoScrollRootId(1)); diff --git a/gfx/webrender_bindings/webrender_ffi.h b/gfx/webrender_bindings/webrender_ffi.h index 7ca21bdc6c76..58b0b1ab6051 100644 --- a/gfx/webrender_bindings/webrender_ffi.h +++ b/gfx/webrender_bindings/webrender_ffi.h @@ -427,6 +427,8 @@ wr_rendered_epochs_delete(WrRenderedEpochs* pipeline_epochs) WR_DESTRUCTOR_SAFE_ WR_INLINE bool wr_window_new(WrWindowId window_id, + uint32_t window_width, + uint32_t window_height, void* aGLContext, bool enable_profiler, WrAPI** out_api, diff --git a/gfx/webrender_traits/Cargo.toml b/gfx/webrender_traits/Cargo.toml index a5e0a2eb1978..aa67b53d0e87 100644 --- a/gfx/webrender_traits/Cargo.toml +++ b/gfx/webrender_traits/Cargo.toml @@ -1,15 +1,12 @@ [package] name = "webrender_traits" -version = "0.20.0" +version = "0.23.1" authors = ["Glenn Watson "] license = "MPL-2.0" repository = "https://github.com/servo/webrender" -build = "build.rs" [features] -default = ["codegen"] nightly = ["euclid/unstable", "serde/unstable"] -codegen = ["serde_codegen", "serde_codegen/with-syntex"] ipc = ["ipc-channel"] [dependencies] @@ -21,15 +18,10 @@ heapsize = "0.3.6" ipc-channel = {version = "0.7", optional = true} offscreen_gl_context = {version = "0.6", features = ["serde"]} serde = "0.9" -serde_derive = {version = "0.9", optional = true} +serde_derive = "0.9" [target.'cfg(target_os = "macos")'.dependencies] core-graphics = "0.7" [target.'cfg(target_os = "windows")'.dependencies] -servo-dwrote = "0.2" - -[build-dependencies.serde_codegen] -version = "0.9" -default_features = false -optional = true +dwrote = "0.3" diff --git a/gfx/webrender_traits/build.rs b/gfx/webrender_traits/build.rs deleted file mode 100644 index c07d8d8a6eba..000000000000 --- a/gfx/webrender_traits/build.rs +++ /dev/null @@ -1,46 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#[cfg(all(feature = "serde_codegen", not(feature = "serde_derive")))] -mod inner { - extern crate serde_codegen; - - use std::env; - use std::path::Path; - - pub fn main() { - let out_dir = env::var_os("OUT_DIR").unwrap(); - - let src = Path::new("src/types.rs"); - let dst = Path::new(&out_dir).join("types.rs"); - - serde_codegen::expand(&src, &dst).unwrap(); - println!("cargo:rerun-if-changed=src/types.rs"); - } -} - -#[cfg(all(feature = "serde_derive", not(feature = "serde_codegen")))] -mod inner { - pub fn main() {} -} - -#[cfg(all(feature = "serde_codegen", feature = "serde_derive"))] -mod inner { - pub fn main() { - panic!("serde_codegen and serde_derive are both used. \ - You probably forgot --no-default-features.") - } -} - -#[cfg(not(any(feature = "serde_codegen", feature = "serde_derive")))] -mod inner { - pub fn main() { - panic!("Neither serde_codegen nor serde_derive are used. " - "You probably want --features serde_derive --no-default-features.") - } -} - -fn main() { - inner::main(); -} diff --git a/gfx/webrender_traits/src/api.rs b/gfx/webrender_traits/src/api.rs index 8dfe8cc01f83..aa404c70b880 100644 --- a/gfx/webrender_traits/src/api.rs +++ b/gfx/webrender_traits/src/api.rs @@ -6,14 +6,15 @@ use byteorder::{LittleEndian, WriteBytesExt}; use channel::{self, MsgSender, PayloadHelperMethods, PayloadSender}; use offscreen_gl_context::{GLContextAttributes, GLLimits}; use std::cell::Cell; -use {ApiMsg, ColorF, DisplayListBuilder, Epoch, ImageDescriptor}; +use {ApiMsg, ColorF, Epoch, ImageDescriptor}; use {FontKey, IdNamespace, ImageKey, NativeFontHandle, PipelineId}; use {RenderApiSender, ResourceId, ScrollEventPhase, ScrollLayerState, ScrollLocation, ServoScrollRootId}; use {GlyphKey, GlyphDimensions, ImageData, WebGLContextId, WebGLCommand, TileSize}; use {DeviceIntSize, DynamicProperties, LayoutPoint, LayoutSize, WorldPoint, PropertyBindingKey, PropertyBindingId}; +use {DeviceUintRect, DeviceUintSize}; use {BuiltDisplayList, AuxiliaryLists}; use VRCompositorCommand; -use ExternalEvent; +use {ExternalEvent, PageZoomFactor}; use std::marker::PhantomData; impl RenderApiSender { @@ -70,6 +71,11 @@ impl RenderApi { self.api_sender.send(msg).unwrap(); } + pub fn delete_font(&self, key: FontKey) { + let msg = ApiMsg::DeleteFont(key); + self.api_sender.send(msg).unwrap(); + } + /// Gets the dimensions for the supplied glyph keys /// /// Note: Internally, the internal texture cache doesn't store @@ -193,6 +199,18 @@ impl RenderApi { self.api_sender.send(msg).unwrap(); } + pub fn set_page_zoom(&self, page_zoom: PageZoomFactor) { + let msg = ApiMsg::SetPageZoom(page_zoom); + self.api_sender.send(msg).unwrap(); + } + + pub fn set_window_parameters(&self, + window_size: DeviceUintSize, + inner_rect: DeviceUintRect) { + let msg = ApiMsg::SetWindowParameters(window_size, inner_rect); + self.api_sender.send(msg).unwrap(); + } + pub fn tick_scrolling_bounce_animations(&self) { let msg = ApiMsg::TickScrollingBounce; self.api_sender.send(msg).unwrap(); diff --git a/gfx/webrender_traits/src/display_list.rs b/gfx/webrender_traits/src/display_list.rs index 66b90f36e390..3bb714642786 100644 --- a/gfx/webrender_traits/src/display_list.rs +++ b/gfx/webrender_traits/src/display_list.rs @@ -284,8 +284,8 @@ impl DisplayListBuilder { bounds: LayoutRect, clip: ClipRegion, z_index: i32, - transform: PropertyBinding, - perspective: LayoutTransform, + transform: Option>, + perspective: Option, mix_blend_mode: MixBlendMode, filters: Vec) { let stacking_context = StackingContext { @@ -355,6 +355,40 @@ impl DisplayListBuilder { self.list.push(item); } + // Don't use this function. It will go away. + // We're using it as a hack in Gecko to retain parts sub-parts of display lists so that + // we can regenerate them without building Gecko display items. + pub fn push_built_display_list(&mut self, dl: BuiltDisplayList, aux: AuxiliaryLists) { + use SpecificDisplayItem::*; + // It's important for us to make sure that all of ItemRange structures are relocated + // when copying from one list to another. To avoid this problem we could use a custom + // derive implementation that would let ItemRanges relocate themselves. + for i in dl.all_display_items() { + let mut i = *i; + match i.item { + Text(ref mut item) => { + item.glyphs = self.auxiliary_lists_builder.add_glyph_instances(aux.glyph_instances(&item.glyphs)); + } + Gradient(ref mut item) => { + item.stops = self.auxiliary_lists_builder.add_gradient_stops(aux.gradient_stops(&item.stops)); + } + RadialGradient(ref mut item) => { + item.stops = self.auxiliary_lists_builder.add_gradient_stops(aux.gradient_stops(&item.stops)); + } + PushStackingContext(ref mut item) => { + item.stacking_context.filters = self.auxiliary_lists_builder.add_filters(aux.filters(&item.stacking_context.filters)); + } + Iframe(_) | PushScrollLayer(_) => { + // We don't support relocating these + panic!(); + } + _ => {} + } + i.clip.complex = self.auxiliary_lists_builder.add_complex_clip_regions(aux.complex_clip_regions(&i.clip.complex)); + self.list.push(i); + } + } + pub fn new_clip_region(&mut self, rect: &LayoutRect, complex: Vec, diff --git a/gfx/webrender_traits/src/lib.rs b/gfx/webrender_traits/src/lib.rs index e6771db6ca24..9a7fdd70934e 100644 --- a/gfx/webrender_traits/src/lib.rs +++ b/gfx/webrender_traits/src/lib.rs @@ -3,7 +3,6 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #![cfg_attr(feature = "nightly", feature(nonzero))] -#![cfg_attr(feature = "serde_derive", feature(rustc_attrs, structural_match))] extern crate app_units; extern crate byteorder; @@ -17,7 +16,6 @@ extern crate heapsize; extern crate ipc_channel; extern crate offscreen_gl_context; extern crate serde; -#[cfg(feature = "serde_derive")] #[macro_use] extern crate serde_derive; @@ -27,10 +25,6 @@ extern crate core_graphics; #[cfg(target_os = "windows")] extern crate dwrote; -#[cfg(feature = "serde_codegen")] -include!(concat!(env!("OUT_DIR"), "/types.rs")); - -#[cfg(feature = "serde_derive")] include!("types.rs"); mod units; diff --git a/gfx/webrender_traits/src/stacking_context.rs b/gfx/webrender_traits/src/stacking_context.rs index 7aca176eecd3..b3cd048017a2 100644 --- a/gfx/webrender_traits/src/stacking_context.rs +++ b/gfx/webrender_traits/src/stacking_context.rs @@ -10,8 +10,8 @@ impl StackingContext { pub fn new(scroll_policy: ScrollPolicy, bounds: LayoutRect, z_index: i32, - transform: PropertyBinding, - perspective: LayoutTransform, + transform: Option>, + perspective: Option, mix_blend_mode: MixBlendMode, filters: Vec, auxiliary_lists_builder: &mut AuxiliaryListsBuilder) diff --git a/gfx/webrender_traits/src/types.rs b/gfx/webrender_traits/src/types.rs index 812e575ed52e..1f3ea2ba1cab 100644 --- a/gfx/webrender_traits/src/types.rs +++ b/gfx/webrender_traits/src/types.rs @@ -30,6 +30,7 @@ pub type TileSize = u16; pub enum ApiMsg { AddRawFont(FontKey, Vec), AddNativeFont(FontKey, NativeFontHandle), + DeleteFont(FontKey), /// Gets the glyph dimensions GetGlyphDimensions(Vec, MsgSender>>), /// Adds an image from the resource cache. @@ -50,7 +51,9 @@ pub enum ApiMsg { BuiltDisplayListDescriptor, AuxiliaryListsDescriptor, bool), + SetPageZoom(PageZoomFactor), SetRootPipeline(PipelineId), + SetWindowParameters(DeviceUintSize, DeviceUintRect), Scroll(ScrollLocation, WorldPoint, ScrollEventPhase), ScrollLayersWithScrollId(LayoutPoint, PipelineId, ServoScrollRootId), TickScrollingBounce, @@ -900,8 +903,8 @@ pub struct StackingContext { pub scroll_policy: ScrollPolicy, pub bounds: LayoutRect, pub z_index: i32, - pub transform: PropertyBinding, - pub perspective: LayoutTransform, + pub transform: Option>, + pub perspective: Option, pub mix_blend_mode: MixBlendMode, pub filters: ItemRange, } @@ -1186,6 +1189,22 @@ pub enum VRCompositorCommand { Release(VRCompositorId) } +/// Represents a desktop style page zoom factor. +#[derive(Clone, Copy, Serialize, Deserialize, Debug)] +pub struct PageZoomFactor(f32); + +impl PageZoomFactor { + /// Construct a new page zoom factor. + pub fn new(scale: f32) -> PageZoomFactor { + PageZoomFactor(scale) + } + + /// Get the page zoom factor as an untyped float. + pub fn get(&self) -> f32 { + self.0 + } +} + // Trait object that handles WebVR commands. // Receives the texture_id associated to the WebGLContext. pub trait VRCompositorHandler: Send { @@ -1197,6 +1216,7 @@ impl fmt::Debug for ApiMsg { match self { &ApiMsg::AddRawFont(..) => { write!(f, "ApiMsg::AddRawFont") } &ApiMsg::AddNativeFont(..) => { write!(f, "ApiMsg::AddNativeFont") } + &ApiMsg::DeleteFont(..) => { write!(f, "ApiMsg::DeleteFont") } &ApiMsg::GetGlyphDimensions(..) => { write!(f, "ApiMsg::GetGlyphDimensions") } &ApiMsg::AddImage(..) => { write!(f, "ApiMsg::AddImage") } &ApiMsg::UpdateImage(..) => { write!(f, "ApiMsg::UpdateImage") } @@ -1216,6 +1236,8 @@ impl fmt::Debug for ApiMsg { &ApiMsg::VRCompositorCommand(..) => { write!(f, "ApiMsg::VRCompositorCommand") } &ApiMsg::ExternalEvent(..) => { write!(f, "ApiMsg::ExternalEvent") } &ApiMsg::ShutDown => { write!(f, "ApiMsg::ShutDown") } + &ApiMsg::SetPageZoom(..) => { write!(f, "ApiMsg::SetPageZoom") } + &ApiMsg::SetWindowParameters(..) => { write!(f, "ApiMsg::SetWindowParameters") } } } } diff --git a/layout/reftests/bugs/reftest.list b/layout/reftests/bugs/reftest.list index 1268f498618f..dbfadb82e817 100644 --- a/layout/reftests/bugs/reftest.list +++ b/layout/reftests/bugs/reftest.list @@ -1810,7 +1810,7 @@ fuzzy-if(skiaContent,1,5) == 956513-1.svg 956513-1-ref.svg == 957770-1.svg 957770-1-ref.svg == 960277-1.html 960277-1-ref.html fuzzy-if(skiaContent,1,80) == 961887-1.html 961887-1-ref.html -fails-if(webrender) == 961887-2.html 961887-2-ref.html +== 961887-2.html 961887-2-ref.html == 961887-3.html 961887-3-ref.html pref(layout.css.overflow-clip-box.enabled,true) fuzzy(50,145) fuzzy-if(asyncPan&&!layersGPUAccelerated,102,3712) == 966992-1.html 966992-1-ref.html skip-if(Android) == 966510-1.html 966510-1-ref.html # scrollable elements other than the root probably won't work well on android until bug 776030 is fixed diff --git a/layout/reftests/css-blending/reftest.list b/layout/reftests/css-blending/reftest.list index bc74651d4abc..051e28305b11 100644 --- a/layout/reftests/css-blending/reftest.list +++ b/layout/reftests/css-blending/reftest.list @@ -48,7 +48,7 @@ fuzzy(2,14400) pref(layout.css.mix-blend-mode.enabled,true) == mix-blend-mode-ch pref(layout.css.mix-blend-mode.enabled,true) == mix-blend-mode-nested-976533.html mix-blend-mode-nested-976533-ref.html pref(layout.css.mix-blend-mode.enabled,true) == mix-blend-mode-culling-1207041.html mix-blend-mode-culling-1207041-ref.html pref(layout.css.mix-blend-mode.enabled,true) == mix-blend-mode-dest-alpha-1135271.html mix-blend-mode-dest-alpha-1135271-ref.html -fails-if(webrender) == clipped-mixblendmode-containing-unclipped-stuff.html clipped-mixblendmode-containing-unclipped-stuff-ref.html +== clipped-mixblendmode-containing-unclipped-stuff.html clipped-mixblendmode-containing-unclipped-stuff-ref.html fuzzy(1,6800) == clipped-opacity-containing-unclipped-mixblendmode.html clipped-opacity-containing-unclipped-mixblendmode-ref.html # Test plan 5.3.1 Blending between the background layers and the background color for an element with background-blend-mode @@ -85,7 +85,7 @@ pref(layout.css.background-blend-mode.enabled,true) == background-blending-backg # Test plan 5.3.11 background-blend-mode for an element with background-attachement pref(layout.css.background-blend-mode.enabled,true) == background-blending-background-attachement-fixed.html background-blending-background-attachement-fixed-ref.html -pref(layout.css.background-blend-mode.enabled,true) fails-if(webrender) == background-blending-background-attachement-fixed-scroll.html background-blending-background-attachement-fixed-scroll-ref.html +pref(layout.css.background-blend-mode.enabled,true) == background-blending-background-attachement-fixed-scroll.html background-blending-background-attachement-fixed-scroll-ref.html pref(layout.css.background-blend-mode.enabled,true) == background-blend-mode-body-image.html background-blend-mode-body-image-ref.html fuzzy-if(Android,4,768) fuzzy-if(gtkWidget,1,132) fuzzy-if(skiaContent,1,800) pref(layout.css.background-blend-mode.enabled,true) == background-blend-mode-body-transparent-image.html background-blend-mode-body-transparent-image-ref.html diff --git a/layout/reftests/svg/reftest.list b/layout/reftests/svg/reftest.list index c3ef17255fdf..b4cc7d11de7c 100644 --- a/layout/reftests/svg/reftest.list +++ b/layout/reftests/svg/reftest.list @@ -432,7 +432,7 @@ pref(layout.css.mix-blend-mode.enabled,true) == blend-normal.svg blend-normal-re #skip-if(Android) pref(layout.css.mix-blend-mode.enabled,true) == blend-saturation.svg blend-saturation-ref.svg #skip-if(Android) pref(layout.css.mix-blend-mode.enabled,true) == blend-screen.svg blend-screen-ref.svg #skip-if(Android) pref(layout.css.mix-blend-mode.enabled,true) == blend-soft-light.svg blend-soft-light-ref.svg -skip-if(Android) pref(layout.css.mix-blend-mode.enabled,true) fails-if(webrender) == blend-difference-stacking.html blend-difference-stacking-ref.html +skip-if(Android) pref(layout.css.mix-blend-mode.enabled,true) == blend-difference-stacking.html blend-difference-stacking-ref.html # test case for Fragment URLs # https://drafts.csswg.org/css-values/#local-urls diff --git a/third_party/rust/dwrote/.cargo-checksum.json b/third_party/rust/dwrote/.cargo-checksum.json new file mode 100644 index 000000000000..18e6d2bcf07a --- /dev/null +++ b/third_party/rust/dwrote/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",".gitignore":"172610b244a5ee8a8e2f1f045058b8abf9291d84bb76bf8779d2fd420419c2d6","Cargo.toml":"c0894413ac3abce23bb93d1284031b29dd00ef7d2f5fcb8573208e0c33280538","README.md":"d69d75705e2582721cbfb2d3b4b2af052c71679057a0b2ac53a22c03f1755bba","appveyor.yml":"2c7b2468dc69bef84860b8900024cb6e1a1c52f6fe1232e8ccd83caaf7c231ca","src/bitmap_render_target.rs":"d3b229f85a9804ac52976431657727b410e7d5253283df046e46d98c196f0a3a","src/com_helpers.rs":"fccb4b36379ae3454a88aa32a8e5c09e46ef5f5626266dde1fe5f40a992de39c","src/comptr.rs":"218435689f505769686e07cfc5428852dda90b849a0d48e670f632307f5edc7c","src/font.rs":"9bdf3134c6ad3639eab3da4419c9b43aad2673797f6fdc65841da2c82e1f3af4","src/font_collection.rs":"969fa3abf141dc3504774886f4783fda4a74cd5a198c643f8a77fc1af4e75258","src/font_face.rs":"9506ca579345ab2b6b5615fc75f8f431e2bb0dbd93123d1d2a21a73c851a5427","src/font_family.rs":"403da9f8f9903cbe7f9f79636497b273f9885e200f53af99f9d4e483f11d6889","src/font_file.rs":"60ad02fc25765a2c113175ea372e98a2be0d84aa65fef9246b6a0192e63ff708","src/font_file_loader_impl.rs":"0d304ad99ff1e6874510a1498223329d798ff75b417e3db7e823a695003dfe92","src/gdi_interop.rs":"98922996afc5b8c8304cb65e7c965419003825dfa172a3e11fe69bf3d768551c","src/glyph_run_analysis.rs":"d30d8b41b047815ab5770c730b7a6d09939f2347b4a4257b87bebec08a5794fe","src/helpers.rs":"5d6f164468234ca8806dc1cea117b42dbfae80cc4c9ae965cb0556efdb364682","src/lib.rs":"07dae7e9a6b8e2970917eade968490e2af90110047a0e16f539647269b12f439","src/rendering_params.rs":"be1d1c433f76926c285d8ecdb747c5d9cc6a6c10c1a1890c0760cd99755ed471","src/test.rs":"d77e45f8866abeea070cbbafd4cbde62d875292e8d191310a04c70091978547c","src/types.rs":"784235c15d61fb0d001373575169aa473c92af18dcbc1709a5b2bbaa3a7ceb22"},"package":"74114b6b49d6731835da7a28a3642651451e315f7f9b9d04e907e65a45681796"} \ No newline at end of file diff --git a/third_party/rust/serde_codegen/.cargo-ok b/third_party/rust/dwrote/.cargo-ok similarity index 100% rename from third_party/rust/serde_codegen/.cargo-ok rename to third_party/rust/dwrote/.cargo-ok diff --git a/third_party/rust/servo-dwrote/.gitignore b/third_party/rust/dwrote/.gitignore similarity index 100% rename from third_party/rust/servo-dwrote/.gitignore rename to third_party/rust/dwrote/.gitignore diff --git a/third_party/rust/dwrote/Cargo.toml b/third_party/rust/dwrote/Cargo.toml new file mode 100644 index 000000000000..e4cc3ed07c23 --- /dev/null +++ b/third_party/rust/dwrote/Cargo.toml @@ -0,0 +1,19 @@ +[package] +name = "dwrote" +description = "Lightweight binding to DirectWrite." +repository = "https://github.com/vvuk/dwrote-rs" +license = "MPL-2.0" +version = "0.3.0" +authors = ["Vladimir Vukicevic "] + +[lib] +name = "dwrote" + +[dependencies] +libc = "0.2" +lazy_static = "0.2" +winapi = "0.2" +kernel32-sys = "0.2" +gdi32-sys = "0.2" +serde = "0.9" +serde_derive = "0.9" diff --git a/third_party/rust/servo-dwrote/README.md b/third_party/rust/dwrote/README.md similarity index 100% rename from third_party/rust/servo-dwrote/README.md rename to third_party/rust/dwrote/README.md diff --git a/third_party/rust/dwrote/appveyor.yml b/third_party/rust/dwrote/appveyor.yml new file mode 100644 index 000000000000..3df037a414fc --- /dev/null +++ b/third_party/rust/dwrote/appveyor.yml @@ -0,0 +1,13 @@ +environment: + PATH: 'C:\msys64\mingw64\bin;C:\msys64\usr\bin;%PATH%;C:\Rust\bin' + +install: + - ps: Start-FileDownload "https://static.rust-lang.org/dist/rust-nightly-x86_64-pc-windows-gnu.msi" + - msiexec /passive /i "rust-nightly-x86_64-pc-windows-gnu.msi" ADDLOCAL=Rustc,Cargo,Std INSTALLDIR=C:\Rust + - rustc -V + - cargo -V + +build: false + +test_script: + - cargo test --verbose diff --git a/third_party/rust/servo-dwrote/src/bitmap_render_target.rs b/third_party/rust/dwrote/src/bitmap_render_target.rs similarity index 100% rename from third_party/rust/servo-dwrote/src/bitmap_render_target.rs rename to third_party/rust/dwrote/src/bitmap_render_target.rs diff --git a/third_party/rust/servo-dwrote/src/com_helpers.rs b/third_party/rust/dwrote/src/com_helpers.rs similarity index 100% rename from third_party/rust/servo-dwrote/src/com_helpers.rs rename to third_party/rust/dwrote/src/com_helpers.rs diff --git a/third_party/rust/servo-dwrote/src/comptr.rs b/third_party/rust/dwrote/src/comptr.rs similarity index 100% rename from third_party/rust/servo-dwrote/src/comptr.rs rename to third_party/rust/dwrote/src/comptr.rs diff --git a/third_party/rust/servo-dwrote/src/font.rs b/third_party/rust/dwrote/src/font.rs similarity index 100% rename from third_party/rust/servo-dwrote/src/font.rs rename to third_party/rust/dwrote/src/font.rs diff --git a/third_party/rust/servo-dwrote/src/font_collection.rs b/third_party/rust/dwrote/src/font_collection.rs similarity index 100% rename from third_party/rust/servo-dwrote/src/font_collection.rs rename to third_party/rust/dwrote/src/font_collection.rs diff --git a/third_party/rust/servo-dwrote/src/font_face.rs b/third_party/rust/dwrote/src/font_face.rs similarity index 100% rename from third_party/rust/servo-dwrote/src/font_face.rs rename to third_party/rust/dwrote/src/font_face.rs diff --git a/third_party/rust/servo-dwrote/src/font_family.rs b/third_party/rust/dwrote/src/font_family.rs similarity index 100% rename from third_party/rust/servo-dwrote/src/font_family.rs rename to third_party/rust/dwrote/src/font_family.rs diff --git a/third_party/rust/servo-dwrote/src/font_file.rs b/third_party/rust/dwrote/src/font_file.rs similarity index 100% rename from third_party/rust/servo-dwrote/src/font_file.rs rename to third_party/rust/dwrote/src/font_file.rs diff --git a/third_party/rust/servo-dwrote/src/font_file_loader_impl.rs b/third_party/rust/dwrote/src/font_file_loader_impl.rs similarity index 100% rename from third_party/rust/servo-dwrote/src/font_file_loader_impl.rs rename to third_party/rust/dwrote/src/font_file_loader_impl.rs diff --git a/third_party/rust/servo-dwrote/src/gdi_interop.rs b/third_party/rust/dwrote/src/gdi_interop.rs similarity index 100% rename from third_party/rust/servo-dwrote/src/gdi_interop.rs rename to third_party/rust/dwrote/src/gdi_interop.rs diff --git a/third_party/rust/servo-dwrote/src/glyph_run_analysis.rs b/third_party/rust/dwrote/src/glyph_run_analysis.rs similarity index 100% rename from third_party/rust/servo-dwrote/src/glyph_run_analysis.rs rename to third_party/rust/dwrote/src/glyph_run_analysis.rs diff --git a/third_party/rust/servo-dwrote/src/helpers.rs b/third_party/rust/dwrote/src/helpers.rs similarity index 100% rename from third_party/rust/servo-dwrote/src/helpers.rs rename to third_party/rust/dwrote/src/helpers.rs diff --git a/third_party/rust/servo-dwrote/src/lib.rs b/third_party/rust/dwrote/src/lib.rs similarity index 97% rename from third_party/rust/servo-dwrote/src/lib.rs rename to third_party/rust/dwrote/src/lib.rs index 73fce9eecd79..dd028ae2f4d5 100644 --- a/third_party/rust/servo-dwrote/src/lib.rs +++ b/third_party/rust/dwrote/src/lib.rs @@ -4,7 +4,6 @@ #![allow(non_upper_case_globals)] -#[cfg(feature = "serde_derive")] #[macro_use] extern crate serde_derive; @@ -17,10 +16,6 @@ extern crate kernel32; extern crate libc; extern crate serde; -#[cfg(feature = "serde_codegen")] -include!(concat!(env!("OUT_DIR"), "/types.rs")); - -#[cfg(feature = "serde_derive")] include!("types.rs"); use winapi::DWRITE_FACTORY_TYPE_SHARED; diff --git a/third_party/rust/servo-dwrote/src/rendering_params.rs b/third_party/rust/dwrote/src/rendering_params.rs similarity index 100% rename from third_party/rust/servo-dwrote/src/rendering_params.rs rename to third_party/rust/dwrote/src/rendering_params.rs diff --git a/third_party/rust/servo-dwrote/src/test.rs b/third_party/rust/dwrote/src/test.rs similarity index 100% rename from third_party/rust/servo-dwrote/src/test.rs rename to third_party/rust/dwrote/src/test.rs diff --git a/third_party/rust/servo-dwrote/src/types.rs b/third_party/rust/dwrote/src/types.rs similarity index 100% rename from third_party/rust/servo-dwrote/src/types.rs rename to third_party/rust/dwrote/src/types.rs diff --git a/third_party/rust/serde_codegen/.cargo-checksum.json b/third_party/rust/serde_codegen/.cargo-checksum.json deleted file mode 100644 index 6444a7756668..000000000000 --- a/third_party/rust/serde_codegen/.cargo-checksum.json +++ /dev/null @@ -1 +0,0 @@ -{"files":{".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","Cargo.toml":"dea9bd4a6e93fc97a4ba26460497c35d3225c4c935f84c5a559094768c25f616","src/bound.rs":"d1f94299052acaeeae0c011c2304b072dec76c7c32469d2b8881c2e380346496","src/de.rs":"c1a4060eeb40de7ac96828cf35dc538ee0df7ba501388092f7e75d31542b11ba","src/lib.rs":"47db5228d2bc20d2d1d2403323de3ad4578f95b9baa5495aa7a095a2eae525dd","src/ser.rs":"361cd76e182d8ddb60560aab7a648dd012673b89e1090b59ff9565ec3c54143c"},"package":"1f94de585a73dfc312ca77194209278a587bf90d3edc6c2d0fc479b0ed71d1f0"} \ No newline at end of file diff --git a/third_party/rust/serde_codegen/Cargo.toml b/third_party/rust/serde_codegen/Cargo.toml deleted file mode 100644 index 9c51a71f4d84..000000000000 --- a/third_party/rust/serde_codegen/Cargo.toml +++ /dev/null @@ -1,32 +0,0 @@ -[package] -name = "serde_codegen" -version = "0.9.0" -authors = ["Erick Tryzelaar "] -license = "MIT/Apache-2.0" -description = "Macros to auto-generate implementations for the serde framework" -homepage = "https://serde.rs" -repository = "https://github.com/serde-rs/serde" -documentation = "https://serde.rs/codegen.html" -keywords = ["serde", "serialization"] -include = ["Cargo.toml", "src/**/*.rs"] - -[features] -default = ["with-syntex"] -unstable = [] -unstable-testing = ["clippy"] -with-syntex = [ - "syntex", - "syntex_syntax", -] -with-syn = [] - -[dependencies] -clippy = { version = "^0.*", optional = true } -quote = "0.3.8" -serde_codegen_internals = { version = "=0.11.3", default-features = false, path = "../serde_codegen_internals" } -syn = { version = "0.10", features = ["aster", "visit"] } -syntex = { version = "^0.54.0", optional = true } -syntex_syntax = { version = "^0.54.0", optional = true } - -[badges] -travis-ci = { repository = "serde-rs/serde" } diff --git a/third_party/rust/serde_codegen/src/bound.rs b/third_party/rust/serde_codegen/src/bound.rs deleted file mode 100644 index fef77ba382d2..000000000000 --- a/third_party/rust/serde_codegen/src/bound.rs +++ /dev/null @@ -1,121 +0,0 @@ -use std::collections::HashSet; - -use syn::{self, aster, visit}; - -use internals::ast::Item; -use internals::attr; - -// Remove the default from every type parameter because in the generated impls -// they look like associated types: "error: associated type bindings are not -// allowed here". -pub fn without_defaults(generics: &syn::Generics) -> syn::Generics { - syn::Generics { - ty_params: generics.ty_params.iter().map(|ty_param| { - syn::TyParam { - default: None, - .. ty_param.clone() - }}).collect(), - .. generics.clone() - } -} - -pub fn with_where_predicates( - generics: &syn::Generics, - predicates: &[syn::WherePredicate], -) -> syn::Generics { - aster::from_generics(generics.clone()) - .with_predicates(predicates.to_vec()) - .build() -} - -pub fn with_where_predicates_from_fields( - item: &Item, - generics: &syn::Generics, - from_field: F, -) -> syn::Generics - where F: Fn(&attr::Field) -> Option<&[syn::WherePredicate]>, -{ - aster::from_generics(generics.clone()) - .with_predicates( - item.body.all_fields() - .flat_map(|field| from_field(&field.attrs)) - .flat_map(|predicates| predicates.to_vec())) - .build() -} - -// Puts the given bound on any generic type parameters that are used in fields -// for which filter returns true. -// -// For example, the following struct needs the bound `A: Serialize, B: Serialize`. -// -// struct S<'b, A, B: 'b, C> { -// a: A, -// b: Option<&'b B> -// #[serde(skip_serializing)] -// c: C, -// } -pub fn with_bound( - item: &Item, - generics: &syn::Generics, - filter: F, - bound: &syn::Path, -) -> syn::Generics - where F: Fn(&attr::Field) -> bool, -{ - struct FindTyParams { - // Set of all generic type parameters on the current struct (A, B, C in - // the example). Initialized up front. - all_ty_params: HashSet, - // Set of generic type parameters used in fields for which filter - // returns true (A and B in the example). Filled in as the visitor sees - // them. - relevant_ty_params: HashSet, - } - impl visit::Visitor for FindTyParams { - fn visit_path(&mut self, path: &syn::Path) { - if let Some(seg) = path.segments.last() { - if seg.ident == "PhantomData" { - // Hardcoded exception, because PhantomData implements - // Serialize and Deserialize whether or not T implements it. - return; - } - } - if !path.global && path.segments.len() == 1 { - let id = path.segments[0].ident.clone(); - if self.all_ty_params.contains(&id) { - self.relevant_ty_params.insert(id); - } - } - visit::walk_path(self, path); - } - } - - let all_ty_params: HashSet<_> = generics.ty_params.iter() - .map(|ty_param| ty_param.ident.clone()) - .collect(); - - let relevant_tys = item.body.all_fields() - .filter(|&field| filter(&field.attrs)) - .map(|field| &field.ty); - - let mut visitor = FindTyParams { - all_ty_params: all_ty_params, - relevant_ty_params: HashSet::new(), - }; - for ty in relevant_tys { - visit::walk_ty(&mut visitor, ty); - } - - aster::from_generics(generics.clone()) - .with_predicates( - generics.ty_params.iter() - .map(|ty_param| ty_param.ident.clone()) - .filter(|id| visitor.relevant_ty_params.contains(id)) - .map(|id| aster::where_predicate() - // the type parameter that is being bounded e.g. T - .bound().build(aster::ty().id(id)) - // the bound e.g. Serialize - .bound().trait_(bound.clone()).build() - .build())) - .build() -} diff --git a/third_party/rust/serde_codegen/src/de.rs b/third_party/rust/serde_codegen/src/de.rs deleted file mode 100644 index e73193b0f23d..000000000000 --- a/third_party/rust/serde_codegen/src/de.rs +++ /dev/null @@ -1,1050 +0,0 @@ -use syn::{self, aster, Ident}; -use quote::{self, Tokens}; - -use bound; -use internals::ast::{Body, Field, Item, Style, Variant}; -use internals::{self, attr}; - -use std::iter; - -pub fn expand_derive_deserialize(item: &syn::MacroInput) -> Result { - let item = { - let ctxt = internals::Ctxt::new(); - let item = Item::from_ast(&ctxt, item); - check_no_str(&ctxt, &item); - try!(ctxt.check()); - item - }; - - let impl_generics = build_impl_generics(&item); - - let ty = aster::ty().path() - .segment(item.ident.clone()).with_generics(impl_generics.clone()).build() - .build(); - - let body = deserialize_body(&item, - &impl_generics, - ty.clone()); - - let where_clause = &impl_generics.where_clause; - - let dummy_const = Ident::new(format!("_IMPL_DESERIALIZE_FOR_{}", item.ident)); - - Ok(quote! { - #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] - const #dummy_const: () = { - extern crate serde as _serde; - #[automatically_derived] - impl #impl_generics _serde::Deserialize for #ty #where_clause { - fn deserialize<__D>(deserializer: __D) -> _serde::export::Result<#ty, __D::Error> - where __D: _serde::Deserializer - #body - } - }; - }) -} - -// All the generics in the input, plus a bound `T: Deserialize` for each generic -// field type that will be deserialized by us, plus a bound `T: Default` for -// each generic field type that will be set to a default value. -fn build_impl_generics(item: &Item) -> syn::Generics { - let generics = bound::without_defaults(item.generics); - - let generics = bound::with_where_predicates_from_fields( - item, &generics, - |attrs| attrs.de_bound()); - - match item.attrs.de_bound() { - Some(predicates) => { - bound::with_where_predicates(&generics, predicates) - } - None => { - let generics = bound::with_bound(item, &generics, - needs_deserialize_bound, - &aster::path().ids(&["_serde", "Deserialize"]).build()); - bound::with_bound(item, &generics, - requires_default, - &aster::path().global().ids(&["std", "default", "Default"]).build()) - } - } -} - -// Fields with a `skip_deserializing` or `deserialize_with` attribute are not -// deserialized by us so we do not generate a bound. Fields with a `bound` -// attribute specify their own bound so we do not generate one. All other fields -// may need a `T: Deserialize` bound where T is the type of the field. -fn needs_deserialize_bound(attrs: &attr::Field) -> bool { - !attrs.skip_deserializing() - && attrs.deserialize_with().is_none() - && attrs.de_bound().is_none() -} - -// Fields with a `default` attribute (not `default=...`), and fields with a -// `skip_deserializing` attribute that do not also have `default=...`. -fn requires_default(attrs: &attr::Field) -> bool { - attrs.default() == &attr::FieldDefault::Default -} - -fn deserialize_body( - item: &Item, - impl_generics: &syn::Generics, - ty: syn::Ty, -) -> Tokens { - match item.body { - Body::Enum(ref variants) => { - deserialize_item_enum( - &item.ident, - impl_generics, - ty, - variants, - &item.attrs) - } - Body::Struct(Style::Struct, ref fields) => { - if fields.iter().any(|field| field.ident.is_none()) { - panic!("struct has unnamed fields"); - } - - deserialize_struct( - &item.ident, - None, - impl_generics, - ty, - fields, - &item.attrs) - } - Body::Struct(Style::Tuple, ref fields) | - Body::Struct(Style::Newtype, ref fields) => { - if fields.iter().any(|field| field.ident.is_some()) { - panic!("tuple struct has named fields"); - } - - deserialize_tuple( - &item.ident, - None, - impl_generics, - ty, - fields, - &item.attrs) - } - Body::Struct(Style::Unit, _) => { - deserialize_unit_struct( - &item.ident, - &item.attrs) - } - } -} - -// Build `__Visitor(PhantomData, PhantomData, ...)` -// -// Returns: -// -// 1. the struct declaration -// 2. the visitor type, including generics -// 3. the expression for instantiating the visitor -fn deserialize_visitor(generics: &syn::Generics) -> (Tokens, Tokens, Tokens) { - if generics.lifetimes.is_empty() && generics.ty_params.is_empty() { - ( - quote! { - struct __Visitor; - }, - quote!(__Visitor), - quote!(__Visitor), - ) - } else { - let where_clause = &generics.where_clause; - - let num_phantoms = generics.lifetimes.len() + generics.ty_params.len(); - - let phantom_types = generics.lifetimes.iter() - .map(|lifetime_def| { - let lifetime = &lifetime_def.lifetime; - quote!(_serde::export::PhantomData<& #lifetime ()>) - }).chain(generics.ty_params.iter() - .map(|ty_param| { - let ident = &ty_param.ident; - quote!(_serde::export::PhantomData<#ident>) - })); - - let all_params = generics.lifetimes.iter() - .map(|lifetime_def| { - let lifetime = &lifetime_def.lifetime; - quote!(#lifetime) - }).chain(generics.ty_params.iter() - .map(|ty_param| { - let ident = &ty_param.ident; - quote!(#ident) - })); - - let ty_param_idents = if generics.ty_params.is_empty() { - None - } else { - let ty_param_idents = generics.ty_params.iter().map(|t| &t.ident); - Some(quote!(::<#(#ty_param_idents),*>)) - }; - - let phantom_exprs = iter::repeat(quote!(_serde::export::PhantomData)).take(num_phantoms); - - ( - quote! { - struct __Visitor #generics ( #(#phantom_types),* ) #where_clause; - }, - quote!(__Visitor <#(#all_params),*> ), - quote!(__Visitor #ty_param_idents ( #(#phantom_exprs),* )), - ) - } -} - -fn deserialize_unit_struct( - type_ident: &syn::Ident, - item_attrs: &attr::Item, -) -> Tokens { - let type_name = item_attrs.name().deserialize_name(); - - let expecting = format!("unit struct {}", type_ident); - - quote!({ - struct __Visitor; - - impl _serde::de::Visitor for __Visitor { - type Value = #type_ident; - - fn expecting(&self, formatter: &mut _serde::export::fmt::Formatter) -> _serde::export::fmt::Result { - formatter.write_str(#expecting) - } - - #[inline] - fn visit_unit<__E>(self) -> _serde::export::Result<#type_ident, __E> - where __E: _serde::de::Error, - { - Ok(#type_ident) - } - - #[inline] - fn visit_seq<__V>(self, _: __V) -> _serde::export::Result<#type_ident, __V::Error> - where __V: _serde::de::SeqVisitor, - { - Ok(#type_ident) - } - } - - deserializer.deserialize_unit_struct(#type_name, __Visitor) - }) -} - -fn deserialize_tuple( - type_ident: &syn::Ident, - variant_ident: Option<&syn::Ident>, - impl_generics: &syn::Generics, - ty: syn::Ty, - fields: &[Field], - item_attrs: &attr::Item, -) -> Tokens { - let where_clause = &impl_generics.where_clause; - - let (visitor_item, visitor_ty, visitor_expr) = deserialize_visitor(impl_generics); - - let is_enum = variant_ident.is_some(); - let type_path = match variant_ident { - Some(variant_ident) => quote!(#type_ident::#variant_ident), - None => quote!(#type_ident), - }; - let expecting = match variant_ident { - Some(variant_ident) => format!("tuple variant {}::{}", type_ident, variant_ident), - None => format!("tuple struct {}", type_ident), - }; - - let nfields = fields.len(); - - let visit_newtype_struct = if !is_enum && nfields == 1 { - Some(deserialize_newtype_struct( - type_ident, - &type_path, - impl_generics, - &fields[0], - )) - } else { - None - }; - - let visit_seq = deserialize_seq( - type_ident, - &type_path, - impl_generics, - fields, - false, - ); - - let dispatch = if is_enum { - quote!(_serde::de::VariantVisitor::visit_tuple(visitor, #nfields, #visitor_expr)) - } else if nfields == 1 { - let type_name = item_attrs.name().deserialize_name(); - quote!(deserializer.deserialize_newtype_struct(#type_name, #visitor_expr)) - } else { - let type_name = item_attrs.name().deserialize_name(); - quote!(deserializer.deserialize_tuple_struct(#type_name, #nfields, #visitor_expr)) - }; - - let all_skipped = fields.iter().all(|field| field.attrs.skip_deserializing()); - let visitor_var = if all_skipped { - quote!(_) - } else { - quote!(mut visitor) - }; - - quote!({ - #visitor_item - - impl #impl_generics _serde::de::Visitor for #visitor_ty #where_clause { - type Value = #ty; - - fn expecting(&self, formatter: &mut _serde::export::fmt::Formatter) -> _serde::export::fmt::Result { - formatter.write_str(#expecting) - } - - #visit_newtype_struct - - #[inline] - fn visit_seq<__V>(self, #visitor_var: __V) -> _serde::export::Result<#ty, __V::Error> - where __V: _serde::de::SeqVisitor - { - #visit_seq - } - } - - #dispatch - }) -} - -fn deserialize_seq( - type_ident: &syn::Ident, - type_path: &Tokens, - impl_generics: &syn::Generics, - fields: &[Field], - is_struct: bool, -) -> Tokens { - let vars = (0..fields.len()).map(field_i as fn(_) -> _); - - let deserialized_count = fields.iter() - .filter(|field| !field.attrs.skip_deserializing()) - .count(); - let expecting = format!("tuple of {} elements", deserialized_count); - - let mut index_in_seq = 0usize; - let let_values = vars.clone().zip(fields) - .map(|(var, field)| { - if field.attrs.skip_deserializing() { - let default = expr_is_missing(&field.attrs); - quote! { - let #var = #default; - } - } else { - let visit = match field.attrs.deserialize_with() { - None => { - let field_ty = &field.ty; - quote!(try!(visitor.visit::<#field_ty>())) - } - Some(path) => { - let (wrapper, wrapper_impl, wrapper_ty) = wrap_deserialize_with( - type_ident, impl_generics, field.ty, path); - quote!({ - #wrapper - #wrapper_impl - try!(visitor.visit::<#wrapper_ty>()).map(|wrap| wrap.value) - }) - } - }; - let assign = quote! { - let #var = match #visit { - Some(value) => { value }, - None => { - return Err(_serde::de::Error::invalid_length(#index_in_seq, &#expecting)); - } - }; - }; - index_in_seq += 1; - assign - } - }); - - let result = if is_struct { - let names = fields.iter().map(|f| &f.ident); - quote! { - #type_path { #( #names: #vars ),* } - } - } else { - quote! { - #type_path ( #(#vars),* ) - } - }; - - quote! { - #(#let_values)* - Ok(#result) - } -} - -fn deserialize_newtype_struct( - type_ident: &syn::Ident, - type_path: &Tokens, - impl_generics: &syn::Generics, - field: &Field, -) -> Tokens { - let value = match field.attrs.deserialize_with() { - None => { - let field_ty = &field.ty; - quote! { - try!(<#field_ty as _serde::Deserialize>::deserialize(__e)) - } - } - Some(path) => { - let (wrapper, wrapper_impl, wrapper_ty) = wrap_deserialize_with( - type_ident, impl_generics, field.ty, path); - quote!({ - #wrapper - #wrapper_impl - try!(<#wrapper_ty as _serde::Deserialize>::deserialize(__e)).value - }) - } - }; - quote! { - #[inline] - fn visit_newtype_struct<__E>(self, __e: __E) -> _serde::export::Result - where __E: _serde::Deserializer, - { - Ok(#type_path(#value)) - } - } -} - -fn deserialize_struct( - type_ident: &syn::Ident, - variant_ident: Option<&syn::Ident>, - impl_generics: &syn::Generics, - ty: syn::Ty, - fields: &[Field], - item_attrs: &attr::Item, -) -> Tokens { - let where_clause = &impl_generics.where_clause; - - let (visitor_item, visitor_ty, visitor_expr) = deserialize_visitor(impl_generics); - - let type_path = match variant_ident { - Some(variant_ident) => quote!(#type_ident::#variant_ident), - None => quote!(#type_ident), - }; - let expecting = match variant_ident { - Some(variant_ident) => format!("struct variant {}::{}", type_ident, variant_ident), - None => format!("struct {}", type_ident), - }; - - let visit_seq = deserialize_seq( - type_ident, - &type_path, - impl_generics, - fields, - true, - ); - - let (field_visitor, fields_stmt, visit_map) = deserialize_struct_visitor( - type_ident, - type_path, - impl_generics, - fields, - item_attrs, - ); - - let is_enum = variant_ident.is_some(); - let dispatch = if is_enum { - quote! { - _serde::de::VariantVisitor::visit_struct(visitor, FIELDS, #visitor_expr) - } - } else { - let type_name = item_attrs.name().deserialize_name(); - quote! { - deserializer.deserialize_struct(#type_name, FIELDS, #visitor_expr) - } - }; - - let all_skipped = fields.iter().all(|field| field.attrs.skip_deserializing()); - let visitor_var = if all_skipped { - quote!(_) - } else { - quote!(mut visitor) - }; - - quote!({ - #field_visitor - - #visitor_item - - impl #impl_generics _serde::de::Visitor for #visitor_ty #where_clause { - type Value = #ty; - - fn expecting(&self, formatter: &mut _serde::export::fmt::Formatter) -> _serde::export::fmt::Result { - formatter.write_str(#expecting) - } - - #[inline] - fn visit_seq<__V>(self, #visitor_var: __V) -> _serde::export::Result<#ty, __V::Error> - where __V: _serde::de::SeqVisitor - { - #visit_seq - } - - #[inline] - fn visit_map<__V>(self, mut visitor: __V) -> _serde::export::Result<#ty, __V::Error> - where __V: _serde::de::MapVisitor - { - #visit_map - } - } - - #fields_stmt - - #dispatch - }) -} - -fn deserialize_item_enum( - type_ident: &syn::Ident, - impl_generics: &syn::Generics, - ty: syn::Ty, - variants: &[Variant], - item_attrs: &attr::Item -) -> Tokens { - let where_clause = &impl_generics.where_clause; - - let type_name = item_attrs.name().deserialize_name(); - - let expecting = format!("enum {}", type_ident); - - let variant_names_idents: Vec<_> = variants.iter() - .enumerate() - .filter(|&(_, variant)| !variant.attrs.skip_deserializing()) - .map(|(i, variant)| (variant.attrs.name().deserialize_name(), field_i(i))) - .collect(); - - let variants_stmt = { - let variant_names = variant_names_idents.iter().map(|&(ref name, _)| name); - quote! { - const VARIANTS: &'static [&'static str] = &[ #(#variant_names),* ]; - } - }; - - let variant_visitor = deserialize_field_visitor( - variant_names_idents, - item_attrs, - true, - ); - - // Match arms to extract a variant from a string - let variant_arms = variants.iter() - .enumerate() - .filter(|&(_, variant)| !variant.attrs.skip_deserializing()) - .map(|(i, variant)| { - let variant_name = field_i(i); - - let block = deserialize_variant( - type_ident, - impl_generics, - ty.clone(), - variant, - item_attrs, - ); - - quote! { - (__Field::#variant_name, visitor) => #block - } - }); - - let all_skipped = variants.iter().all(|variant| variant.attrs.skip_deserializing()); - let match_variant = if all_skipped { - // This is an empty enum like `enum Impossible {}` or an enum in which - // all variants have `#[serde(skip_deserializing)]`. - quote! { - // FIXME: Once we drop support for Rust 1.15: - // let Err(err) = visitor.visit_variant::<__Field>(); - // Err(err) - visitor.visit_variant::<__Field>().map(|(impossible, _)| match impossible {}) - } - } else { - quote! { - match try!(visitor.visit_variant()) { - #(#variant_arms)* - } - } - }; - - let (visitor_item, visitor_ty, visitor_expr) = deserialize_visitor(impl_generics); - - quote!({ - #variant_visitor - - #visitor_item - - impl #impl_generics _serde::de::Visitor for #visitor_ty #where_clause { - type Value = #ty; - - fn expecting(&self, formatter: &mut _serde::export::fmt::Formatter) -> _serde::export::fmt::Result { - formatter.write_str(#expecting) - } - - fn visit_enum<__V>(self, visitor: __V) -> _serde::export::Result<#ty, __V::Error> - where __V: _serde::de::EnumVisitor, - { - #match_variant - } - } - - #variants_stmt - - deserializer.deserialize_enum(#type_name, VARIANTS, #visitor_expr) - }) -} - -fn deserialize_variant( - type_ident: &syn::Ident, - generics: &syn::Generics, - ty: syn::Ty, - variant: &Variant, - item_attrs: &attr::Item, -) -> Tokens { - let variant_ident = &variant.ident; - - match variant.style { - Style::Unit => { - quote!({ - try!(_serde::de::VariantVisitor::visit_unit(visitor)); - Ok(#type_ident::#variant_ident) - }) - } - Style::Newtype => { - deserialize_newtype_variant( - type_ident, - variant_ident, - generics, - &variant.fields[0], - ) - } - Style::Tuple => { - deserialize_tuple( - type_ident, - Some(variant_ident), - generics, - ty, - &variant.fields, - item_attrs, - ) - } - Style::Struct => { - deserialize_struct( - type_ident, - Some(variant_ident), - generics, - ty, - &variant.fields, - item_attrs, - ) - } - } -} - -fn deserialize_newtype_variant( - type_ident: &syn::Ident, - variant_ident: &syn::Ident, - impl_generics: &syn::Generics, - field: &Field, -) -> Tokens { - let visit = match field.attrs.deserialize_with() { - None => { - let field_ty = &field.ty; - quote! { - try!(_serde::de::VariantVisitor::visit_newtype::<#field_ty>(visitor)) - } - } - Some(path) => { - let (wrapper, wrapper_impl, wrapper_ty) = wrap_deserialize_with( - type_ident, impl_generics, field.ty, path); - quote!({ - #wrapper - #wrapper_impl - try!(_serde::de::VariantVisitor::visit_newtype::<#wrapper_ty>(visitor)).value - }) - } - }; - quote! { - Ok(#type_ident::#variant_ident(#visit)), - } -} - -fn deserialize_field_visitor( - fields: Vec<(String, Ident)>, - item_attrs: &attr::Item, - is_variant: bool, -) -> Tokens { - let field_strs = fields.iter().map(|&(ref name, _)| name); - let field_bytes = fields.iter().map(|&(ref name, _)| quote::ByteStr(name)); - let field_idents: &Vec<_> = &fields.iter().map(|&(_, ref ident)| ident).collect(); - - let ignore_variant = if is_variant || item_attrs.deny_unknown_fields() { - None - } else { - Some(quote!(__ignore,)) - }; - - let visit_index = if is_variant { - let variant_indices = 0u32..; - let fallthrough_msg = format!("variant index 0 <= i < {}", fields.len()); - Some(quote! { - fn visit_u32<__E>(self, value: u32) -> _serde::export::Result<__Field, __E> - where __E: _serde::de::Error - { - match value { - #( - #variant_indices => Ok(__Field::#field_idents), - )* - _ => Err(_serde::de::Error::invalid_value( - _serde::de::Unexpected::Unsigned(value as u64), - &#fallthrough_msg)) - } - } - }) - } else { - None - }; - - let fallthrough_arm = if is_variant { - quote! { - Err(_serde::de::Error::unknown_variant(value, VARIANTS)) - } - } else if item_attrs.deny_unknown_fields() { - quote! { - Err(_serde::de::Error::unknown_field(value, FIELDS)) - } - } else { - quote! { - Ok(__Field::__ignore) - } - }; - - let bytes_to_str = if is_variant || item_attrs.deny_unknown_fields() { - Some(quote! { - // TODO https://github.com/serde-rs/serde/issues/666 - // update this to use str::from_utf8(value).unwrap_or("���") on no_std - let value = &_serde::export::from_utf8_lossy(value); - }) - } else { - None - }; - - quote! { - #[allow(non_camel_case_types)] - enum __Field { - #(#field_idents,)* - #ignore_variant - } - - impl _serde::Deserialize for __Field { - #[inline] - fn deserialize<__D>(deserializer: __D) -> _serde::export::Result<__Field, __D::Error> - where __D: _serde::Deserializer, - { - struct __FieldVisitor; - - impl _serde::de::Visitor for __FieldVisitor { - type Value = __Field; - - fn expecting(&self, formatter: &mut _serde::export::fmt::Formatter) -> _serde::export::fmt::Result { - formatter.write_str("field name") - } - - #visit_index - - fn visit_str<__E>(self, value: &str) -> _serde::export::Result<__Field, __E> - where __E: _serde::de::Error - { - match value { - #( - #field_strs => Ok(__Field::#field_idents), - )* - _ => #fallthrough_arm - } - } - - fn visit_bytes<__E>(self, value: &[u8]) -> _serde::export::Result<__Field, __E> - where __E: _serde::de::Error - { - match value { - #( - #field_bytes => Ok(__Field::#field_idents), - )* - _ => { - #bytes_to_str - #fallthrough_arm - } - } - } - } - - deserializer.deserialize_struct_field(__FieldVisitor) - } - } - } -} - -fn deserialize_struct_visitor( - type_ident: &syn::Ident, - struct_path: Tokens, - impl_generics: &syn::Generics, - fields: &[Field], - item_attrs: &attr::Item, -) -> (Tokens, Tokens, Tokens) { - let field_names_idents: Vec<_> = fields.iter() - .enumerate() - .filter(|&(_, field)| !field.attrs.skip_deserializing()) - .map(|(i, field)| (field.attrs.name().deserialize_name(), field_i(i))) - .collect(); - - let fields_stmt = { - let field_names = field_names_idents.iter().map(|&(ref name, _)| name); - quote! { - const FIELDS: &'static [&'static str] = &[ #(#field_names),* ]; - } - }; - - let field_visitor = deserialize_field_visitor( - field_names_idents, - item_attrs, - false, - ); - - let visit_map = deserialize_map( - type_ident, - struct_path, - impl_generics, - fields, - item_attrs, - ); - - (field_visitor, fields_stmt, visit_map) -} - -fn deserialize_map( - type_ident: &syn::Ident, - struct_path: Tokens, - impl_generics: &syn::Generics, - fields: &[Field], - item_attrs: &attr::Item, -) -> Tokens { - // Create the field names for the fields. - let fields_names: Vec<_> = fields.iter() - .enumerate() - .map(|(i, field)| (field, field_i(i))) - .collect(); - - // Declare each field that will be deserialized. - let let_values = fields_names.iter() - .filter(|&&(field, _)| !field.attrs.skip_deserializing()) - .map(|&(field, ref name)| { - let field_ty = &field.ty; - quote! { - let mut #name: Option<#field_ty> = None; - } - }); - - // Match arms to extract a value for a field. - let value_arms = fields_names.iter() - .filter(|&&(field, _)| !field.attrs.skip_deserializing()) - .map(|&(field, ref name)| { - let deser_name = field.attrs.name().deserialize_name(); - - let visit = match field.attrs.deserialize_with() { - None => { - let field_ty = &field.ty; - quote! { - try!(visitor.visit_value::<#field_ty>()) - } - } - Some(path) => { - let (wrapper, wrapper_impl, wrapper_ty) = wrap_deserialize_with( - type_ident, impl_generics, field.ty, path); - quote!({ - #wrapper - #wrapper_impl - try!(visitor.visit_value::<#wrapper_ty>()).value - }) - } - }; - quote! { - __Field::#name => { - if #name.is_some() { - return Err(<__V::Error as _serde::de::Error>::duplicate_field(#deser_name)); - } - #name = Some(#visit); - } - } - }); - - // Visit ignored values to consume them - let ignored_arm = if item_attrs.deny_unknown_fields() { - None - } else { - Some(quote! { - _ => { let _ = try!(visitor.visit_value::<_serde::de::impls::IgnoredAny>()); } - }) - }; - - let all_skipped = fields.iter().all(|field| field.attrs.skip_deserializing()); - let match_keys = if item_attrs.deny_unknown_fields() && all_skipped { - quote! { - // FIXME: Once we drop support for Rust 1.15: - // let None::<__Field> = try!(visitor.visit_key()); - try!(visitor.visit_key::<__Field>()).map(|impossible| match impossible {}); - } - } else { - quote! { - while let Some(key) = try!(visitor.visit_key::<__Field>()) { - match key { - #(#value_arms)* - #ignored_arm - } - } - } - }; - - let extract_values = fields_names.iter() - .filter(|&&(field, _)| !field.attrs.skip_deserializing()) - .map(|&(field, ref name)| { - let missing_expr = expr_is_missing(&field.attrs); - - quote! { - let #name = match #name { - Some(#name) => #name, - None => #missing_expr - }; - } - }); - - let result = fields_names.iter() - .map(|&(field, ref name)| { - let ident = field.ident.clone().expect("struct contains unnamed fields"); - let value = if field.attrs.skip_deserializing() { - expr_is_missing(&field.attrs) - } else { - quote!(#name) - }; - quote!(#ident: #value) - }); - - quote! { - #(#let_values)* - - #match_keys - - #(#extract_values)* - - Ok(#struct_path { #(#result),* }) - } -} - -fn field_i(i: usize) -> Ident { - Ident::new(format!("__field{}", i)) -} - -/// This function wraps the expression in `#[serde(deserialize_with="...")]` in -/// a trait to prevent it from accessing the internal `Deserialize` state. -fn wrap_deserialize_with( - type_ident: &syn::Ident, - impl_generics: &syn::Generics, - field_ty: &syn::Ty, - deserialize_with: &syn::Path, -) -> (Tokens, Tokens, syn::Path) { - // Quasi-quoting doesn't do a great job of expanding generics into paths, - // so manually build it. - let wrapper_ty = aster::path() - .segment("__SerdeDeserializeWithStruct") - .with_generics(impl_generics.clone()) - .build() - .build(); - - let where_clause = &impl_generics.where_clause; - - let phantom_ty = aster::path() - .segment(type_ident) - .with_generics(aster::from_generics(impl_generics.clone()) - .strip_ty_params() - .build()) - .build() - .build(); - - ( - quote! { - struct __SerdeDeserializeWithStruct #impl_generics #where_clause { - value: #field_ty, - phantom: _serde::export::PhantomData<#phantom_ty>, - } - }, - quote! { - impl #impl_generics _serde::Deserialize for #wrapper_ty #where_clause { - fn deserialize<__D>(__d: __D) -> _serde::export::Result - where __D: _serde::Deserializer - { - let value = try!(#deserialize_with(__d)); - Ok(__SerdeDeserializeWithStruct { - value: value, - phantom: _serde::export::PhantomData, - }) - } - } - }, - wrapper_ty, - ) -} - -fn expr_is_missing(attrs: &attr::Field) -> Tokens { - match *attrs.default() { - attr::FieldDefault::Default => { - return quote!(_serde::export::Default::default()); - } - attr::FieldDefault::Path(ref path) => { - return quote!(#path()); - } - attr::FieldDefault::None => { /* below */ } - } - - let name = attrs.name().deserialize_name(); - match attrs.deserialize_with() { - None => { - quote! { - try!(_serde::de::private::missing_field(#name)) - } - } - Some(_) => { - quote! { - return Err(<__V::Error as _serde::de::Error>::missing_field(#name)) - } - } - } -} - -fn check_no_str(cx: &internals::Ctxt, item: &Item) { - let fail = || { - cx.error( - "Serde does not support deserializing fields of type &str; \ - consider using String instead"); - }; - - for field in item.body.all_fields() { - if field.attrs.skip_deserializing() - || field.attrs.deserialize_with().is_some() { continue } - - if let syn::Ty::Rptr(_, ref inner) = *field.ty { - if let syn::Ty::Path(_, ref path) = inner.ty { - if path.segments.len() == 1 && path.segments[0].ident == "str" { - fail(); - return; - } - } - } - } -} diff --git a/third_party/rust/serde_codegen/src/lib.rs b/third_party/rust/serde_codegen/src/lib.rs deleted file mode 100644 index 9850fecce1c1..000000000000 --- a/third_party/rust/serde_codegen/src/lib.rs +++ /dev/null @@ -1,171 +0,0 @@ -#![cfg_attr(feature = "clippy", plugin(clippy))] -#![cfg_attr(feature = "clippy", feature(plugin))] -#![cfg_attr(feature = "clippy", allow(too_many_arguments))] -#![cfg_attr(feature = "clippy", allow(used_underscore_binding))] - -// The `quote!` macro requires deep recursion. -#![recursion_limit = "192"] - -extern crate serde_codegen_internals as internals; - -#[cfg(feature = "with-syntex")] -extern crate syntex; - -#[cfg(feature = "with-syntex")] -extern crate syntex_syntax as syntax; - -extern crate syn; -#[macro_use] -extern crate quote; - -#[cfg(feature = "with-syntex")] -use std::path::Path; - -mod bound; -mod de; -mod ser; - -#[cfg(feature = "with-syntex")] -fn syntex_registry() -> syntex::Registry { - use syntax::{ast, fold}; - - /// Strip the serde attributes from the crate. - #[cfg(feature = "with-syntex")] - fn strip_attributes(krate: ast::Crate) -> ast::Crate { - /// Helper folder that strips the serde attributes after the extensions have been expanded. - struct StripAttributeFolder; - - impl fold::Folder for StripAttributeFolder { - fn fold_attribute(&mut self, attr: ast::Attribute) -> Option { - if attr.value.name == "serde" { - if let ast::MetaItemKind::List(..) = attr.value.node { - return None; - } - } - Some(attr) - } - - fn fold_mac(&mut self, mac: ast::Mac) -> ast::Mac { - fold::noop_fold_mac(mac, self) - } - } - - fold::Folder::fold_crate(&mut StripAttributeFolder, krate) - } - - let mut reg = syntex::Registry::new(); - - reg.add_attr("feature(custom_derive)"); - reg.add_attr("feature(custom_attribute)"); - - reg.add_decorator("derive_Serialize", shim::expand_derive_serialize); - reg.add_decorator("derive_Deserialize", shim::expand_derive_deserialize); - - reg.add_post_expansion_pass(strip_attributes); - - reg -} - -#[cfg(feature = "with-syntex")] -pub fn expand_str(src: &str) -> Result { - let src = src.to_owned(); - - let expand_thread = move || { - syntex_registry().expand_str("", "", &src) - }; - - syntex::with_extra_stack(expand_thread) -} - -#[cfg(feature = "with-syntex")] -pub fn expand(src: S, dst: D) -> Result<(), syntex::Error> - where S: AsRef, - D: AsRef, -{ - let src = src.as_ref().to_owned(); - let dst = dst.as_ref().to_owned(); - - let expand_thread = move || { - syntex_registry().expand("", src, dst) - }; - - syntex::with_extra_stack(expand_thread) -} - -macro_rules! shim { - ($name:ident $pkg:ident :: $func:ident) => { - pub fn $func( - cx: &mut ::syntax::ext::base::ExtCtxt, - span: ::syntax::codemap::Span, - meta_item: &::syntax::ast::MetaItem, - annotatable: &::syntax::ext::base::Annotatable, - push: &mut FnMut(::syntax::ext::base::Annotatable) - ) { - let item = match *annotatable { - ::syntax::ext::base::Annotatable::Item(ref item) => item, - _ => { - cx.span_err( - meta_item.span, - concat!("`#[derive(", - stringify!($name), - ")]` may only be applied to structs and enums")); - return; - } - }; - - use syntax::{attr, ast, visit}; - struct MarkSerdeAttributesUsed; - impl<'a> visit::Visitor<'a> for MarkSerdeAttributesUsed { - fn visit_attribute(&mut self, attr: &ast::Attribute) { - if attr.value.name == "serde" { - if let ast::MetaItemKind::List(..) = attr.value.node { - attr::mark_used(attr); - } - } - } - } - visit::walk_item(&mut MarkSerdeAttributesUsed, item); - - use syntax::print::pprust; - let s = pprust::item_to_string(item); - - use {syn, $pkg}; - let syn_item = syn::parse_macro_input(&s).unwrap(); - let expanded = match $pkg::$func(&syn_item) { - Ok(expanded) => expanded.to_string(), - Err(msg) => { - cx.span_err(span, &msg); - return; - } - }; - - use syntax::parse; - let name = stringify!($name).to_string(); - let sess = cx.parse_sess; - let impl_item = parse::parse_item_from_source_str(name, expanded, sess); - push(::syntax::ext::base::Annotatable::Item(impl_item.unwrap().unwrap())); - } - }; -} - -#[cfg(feature = "with-syntex")] -mod shim { - shim!(Serialize ser::expand_derive_serialize); - shim!(Deserialize de::expand_derive_deserialize); -} - -#[cfg(feature = "with-syn")] -#[doc(hidden)] -/// Not public API. Use the serde_derive crate. -pub fn expand_derive_serialize(item: &str) -> Result { - let syn_item = syn::parse_macro_input(item).unwrap(); - ser::expand_derive_serialize(&syn_item) -} - -#[cfg(feature = "with-syn")] -#[doc(hidden)] -/// Not public API. Use the serde_derive crate. -pub fn expand_derive_deserialize(item: &str) -> Result { - let syn_item = syn::parse_macro_input(item).unwrap(); - de::expand_derive_deserialize(&syn_item) -} diff --git a/third_party/rust/serde_codegen/src/ser.rs b/third_party/rust/serde_codegen/src/ser.rs deleted file mode 100644 index c8efe1afa2d2..000000000000 --- a/third_party/rust/serde_codegen/src/ser.rs +++ /dev/null @@ -1,570 +0,0 @@ -use syn::{self, aster, Ident}; -use quote::Tokens; - -use bound; -use internals::ast::{Body, Field, Item, Style, Variant}; -use internals::{self, attr}; - -pub fn expand_derive_serialize(item: &syn::MacroInput) -> Result { - let ctxt = internals::Ctxt::new(); - let item = Item::from_ast(&ctxt, item); - try!(ctxt.check()); - - let impl_generics = build_impl_generics(&item); - - let ty = aster::ty().path() - .segment(item.ident.clone()).with_generics(impl_generics.clone()).build() - .build(); - - let body = serialize_body(&item, - &impl_generics, - ty.clone()); - - let where_clause = &impl_generics.where_clause; - - let dummy_const = Ident::new(format!("_IMPL_SERIALIZE_FOR_{}", item.ident)); - - Ok(quote! { - #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] - const #dummy_const: () = { - extern crate serde as _serde; - #[automatically_derived] - impl #impl_generics _serde::Serialize for #ty #where_clause { - fn serialize<__S>(&self, _serializer: __S) -> _serde::export::Result<__S::Ok, __S::Error> - where __S: _serde::Serializer - { - #body - } - } - }; - }) -} - -// All the generics in the input, plus a bound `T: Serialize` for each generic -// field type that will be serialized by us. -fn build_impl_generics(item: &Item) -> syn::Generics { - let generics = bound::without_defaults(item.generics); - - let generics = bound::with_where_predicates_from_fields( - item, &generics, - |attrs| attrs.ser_bound()); - - match item.attrs.ser_bound() { - Some(predicates) => { - bound::with_where_predicates(&generics, predicates) - } - None => { - bound::with_bound(item, &generics, - needs_serialize_bound, - &aster::path().ids(&["_serde", "Serialize"]).build()) - } - } -} - -// Fields with a `skip_serializing` or `serialize_with` attribute are not -// serialized by us so we do not generate a bound. Fields with a `bound` -// attribute specify their own bound so we do not generate one. All other fields -// may need a `T: Serialize` bound where T is the type of the field. -fn needs_serialize_bound(attrs: &attr::Field) -> bool { - !attrs.skip_serializing() - && attrs.serialize_with().is_none() - && attrs.ser_bound().is_none() -} - -fn serialize_body( - item: &Item, - impl_generics: &syn::Generics, - ty: syn::Ty, -) -> Tokens { - match item.body { - Body::Enum(ref variants) => { - serialize_item_enum( - &item.ident, - impl_generics, - ty, - variants, - &item.attrs) - } - Body::Struct(Style::Struct, ref fields) => { - if fields.iter().any(|field| field.ident.is_none()) { - panic!("struct has unnamed fields"); - } - - serialize_struct( - impl_generics, - ty, - fields, - &item.attrs) - } - Body::Struct(Style::Tuple, ref fields) => { - if fields.iter().any(|field| field.ident.is_some()) { - panic!("tuple struct has named fields"); - } - - serialize_tuple_struct( - impl_generics, - ty, - fields, - &item.attrs) - } - Body::Struct(Style::Newtype, ref fields) => { - serialize_newtype_struct( - impl_generics, - ty, - &fields[0], - &item.attrs) - } - Body::Struct(Style::Unit, _) => { - serialize_unit_struct( - &item.attrs) - } - } -} - -fn serialize_unit_struct(item_attrs: &attr::Item) -> Tokens { - let type_name = item_attrs.name().serialize_name(); - - quote! { - _serializer.serialize_unit_struct(#type_name) - } -} - -fn serialize_newtype_struct( - impl_generics: &syn::Generics, - item_ty: syn::Ty, - field: &Field, - item_attrs: &attr::Item, -) -> Tokens { - let type_name = item_attrs.name().serialize_name(); - - let mut field_expr = quote!(&self.0); - if let Some(path) = field.attrs.serialize_with() { - field_expr = wrap_serialize_with( - &item_ty, impl_generics, field.ty, path, field_expr); - } - - quote! { - _serializer.serialize_newtype_struct(#type_name, #field_expr) - } -} - -fn serialize_tuple_struct( - impl_generics: &syn::Generics, - ty: syn::Ty, - fields: &[Field], - item_attrs: &attr::Item, -) -> Tokens { - let serialize_stmts = serialize_tuple_struct_visitor( - ty.clone(), - fields, - impl_generics, - false, - quote!(_serde::ser::SerializeTupleStruct::serialize_field), - ); - - let type_name = item_attrs.name().serialize_name(); - let len = serialize_stmts.len(); - let let_mut = mut_if(len > 0); - - quote! { - let #let_mut __serde_state = try!(_serializer.serialize_tuple_struct(#type_name, #len)); - #(#serialize_stmts)* - _serde::ser::SerializeTupleStruct::end(__serde_state) - } -} - -fn serialize_struct( - impl_generics: &syn::Generics, - ty: syn::Ty, - fields: &[Field], - item_attrs: &attr::Item, -) -> Tokens { - let serialize_fields = serialize_struct_visitor( - ty.clone(), - fields, - impl_generics, - false, - quote!(_serde::ser::SerializeStruct::serialize_field), - ); - - let type_name = item_attrs.name().serialize_name(); - - let mut serialized_fields = fields.iter() - .filter(|&field| !field.attrs.skip_serializing()) - .peekable(); - - let let_mut = mut_if(serialized_fields.peek().is_some()); - - let len = serialized_fields - .map(|field| { - let ident = field.ident.clone().expect("struct has unnamed fields"); - let field_expr = quote!(&self.#ident); - - match field.attrs.skip_serializing_if() { - Some(path) => quote!(if #path(#field_expr) { 0 } else { 1 }), - None => quote!(1), - } - }) - .fold(quote!(0), |sum, expr| quote!(#sum + #expr)); - - quote! { - let #let_mut __serde_state = try!(_serializer.serialize_struct(#type_name, #len)); - #(#serialize_fields)* - _serde::ser::SerializeStruct::end(__serde_state) - } -} - -fn serialize_item_enum( - type_ident: &syn::Ident, - impl_generics: &syn::Generics, - ty: syn::Ty, - variants: &[Variant], - item_attrs: &attr::Item, -) -> Tokens { - let arms: Vec<_> = - variants.iter() - .enumerate() - .map(|(variant_index, variant)| { - serialize_variant( - type_ident, - impl_generics, - ty.clone(), - variant, - variant_index, - item_attrs, - ) - }) - .collect(); - - quote! { - match *self { - #(#arms)* - } - } -} - -fn serialize_variant( - type_ident: &syn::Ident, - generics: &syn::Generics, - ty: syn::Ty, - variant: &Variant, - variant_index: usize, - item_attrs: &attr::Item, -) -> Tokens { - let type_name = item_attrs.name().serialize_name(); - - let variant_ident = variant.ident.clone(); - let variant_name = variant.attrs.name().serialize_name(); - - if variant.attrs.skip_serializing() { - let skipped_msg = format!("the enum variant {}::{} cannot be serialized", - type_ident, variant_ident); - let skipped_err = quote! { - Err(_serde::ser::Error::custom(#skipped_msg)) - }; - let fields_pat = match variant.style { - Style::Unit => quote!(), - Style::Newtype | Style::Tuple => quote!( (..) ), - Style::Struct => quote!( {..} ), - }; - quote! { - #type_ident::#variant_ident #fields_pat => #skipped_err, - } - } else { // variant wasn't skipped - match variant.style { - Style::Unit => { - quote! { - #type_ident::#variant_ident => - _serde::Serializer::serialize_unit_variant( - _serializer, - #type_name, - #variant_index, - #variant_name, - ), - } - }, - Style::Newtype => { - let block = serialize_newtype_variant( - type_name, - variant_index, - variant_name, - ty, - generics, - &variant.fields[0], - ); - - quote! { - #type_ident::#variant_ident(ref __simple_value) => #block, - } - }, - Style::Tuple => { - let field_names = (0 .. variant.fields.len()) - .map(|i| Ident::new(format!("__field{}", i))); - - let block = serialize_tuple_variant( - type_name, - variant_index, - variant_name, - generics, - ty, - &variant.fields, - ); - - quote! { - #type_ident::#variant_ident(#(ref #field_names),*) => { #block } - } - } - Style::Struct => { - let fields = variant.fields.iter() - .map(|f| f.ident.clone().expect("struct variant has unnamed fields")); - - let block = serialize_struct_variant( - variant_index, - variant_name, - generics, - ty, - &variant.fields, - item_attrs, - ); - - quote! { - #type_ident::#variant_ident { #(ref #fields),* } => { #block } - } - } - } - } -} - -fn serialize_newtype_variant( - type_name: String, - variant_index: usize, - variant_name: String, - item_ty: syn::Ty, - generics: &syn::Generics, - field: &Field, -) -> Tokens { - let mut field_expr = quote!(__simple_value); - if let Some(path) = field.attrs.serialize_with() { - field_expr = wrap_serialize_with( - &item_ty, generics, field.ty, path, field_expr); - } - - quote! { - _serde::Serializer::serialize_newtype_variant( - _serializer, - #type_name, - #variant_index, - #variant_name, - #field_expr, - ) - } -} - -fn serialize_tuple_variant( - type_name: String, - variant_index: usize, - variant_name: String, - generics: &syn::Generics, - structure_ty: syn::Ty, - fields: &[Field], -) -> Tokens { - let serialize_stmts = serialize_tuple_struct_visitor( - structure_ty, - fields, - generics, - true, - quote!(_serde::ser::SerializeTupleVariant::serialize_field), - ); - - let len = serialize_stmts.len(); - let let_mut = mut_if(len > 0); - - quote! { - let #let_mut __serde_state = try!(_serializer.serialize_tuple_variant( - #type_name, - #variant_index, - #variant_name, - #len)); - #(#serialize_stmts)* - _serde::ser::SerializeTupleVariant::end(__serde_state) - } -} - -fn serialize_struct_variant( - variant_index: usize, - variant_name: String, - generics: &syn::Generics, - ty: syn::Ty, - fields: &[Field], - item_attrs: &attr::Item, -) -> Tokens { - let serialize_fields = serialize_struct_visitor( - ty.clone(), - fields, - generics, - true, - quote!(_serde::ser::SerializeStructVariant::serialize_field), - ); - - let item_name = item_attrs.name().serialize_name(); - - let mut serialized_fields = fields.iter() - .filter(|&field| !field.attrs.skip_serializing()) - .peekable(); - - let let_mut = mut_if(serialized_fields.peek().is_some()); - - let len = serialized_fields - .map(|field| { - let ident = field.ident.clone().expect("struct has unnamed fields"); - - match field.attrs.skip_serializing_if() { - Some(path) => quote!(if #path(#ident) { 0 } else { 1 }), - None => quote!(1), - } - }) - .fold(quote!(0), |sum, expr| quote!(#sum + #expr)); - - quote! { - let #let_mut __serde_state = try!(_serializer.serialize_struct_variant( - #item_name, - #variant_index, - #variant_name, - #len, - )); - #(#serialize_fields)* - _serde::ser::SerializeStructVariant::end(__serde_state) - } -} - -fn serialize_tuple_struct_visitor( - structure_ty: syn::Ty, - fields: &[Field], - generics: &syn::Generics, - is_enum: bool, - func: Tokens, -) -> Vec { - fields.iter() - .enumerate() - .map(|(i, field)| { - let mut field_expr = if is_enum { - let id = Ident::new(format!("__field{}", i)); - quote!(#id) - } else { - let i = Ident::new(i); - quote!(&self.#i) - }; - - let skip = field.attrs.skip_serializing_if() - .map(|path| quote!(#path(#field_expr))); - - if let Some(path) = field.attrs.serialize_with() { - field_expr = wrap_serialize_with( - &structure_ty, generics, field.ty, path, field_expr); - } - - let ser = quote! { - try!(#func(&mut __serde_state, #field_expr)); - }; - - match skip { - None => ser, - Some(skip) => quote!(if !#skip { #ser }), - } - }) - .collect() -} - -fn serialize_struct_visitor( - structure_ty: syn::Ty, - fields: &[Field], - generics: &syn::Generics, - is_enum: bool, - func: Tokens, -) -> Vec { - fields.iter() - .filter(|&field| !field.attrs.skip_serializing()) - .map(|field| { - let ident = field.ident.clone().expect("struct has unnamed field"); - let mut field_expr = if is_enum { - quote!(#ident) - } else { - quote!(&self.#ident) - }; - - let key_expr = field.attrs.name().serialize_name(); - - let skip = field.attrs.skip_serializing_if() - .map(|path| quote!(#path(#field_expr))); - - if let Some(path) = field.attrs.serialize_with() { - field_expr = wrap_serialize_with( - &structure_ty, generics, field.ty, path, field_expr) - } - - let ser = quote! { - try!(#func(&mut __serde_state, #key_expr, #field_expr)); - }; - - match skip { - None => ser, - Some(skip) => quote!(if !#skip { #ser }), - } - }) - .collect() -} - -fn wrap_serialize_with( - item_ty: &syn::Ty, - generics: &syn::Generics, - field_ty: &syn::Ty, - path: &syn::Path, - value: Tokens, -) -> Tokens { - let where_clause = &generics.where_clause; - - let wrapper_generics = aster::from_generics(generics.clone()) - .add_lifetime_bound("'__a") - .lifetime_name("'__a") - .build(); - - let wrapper_ty = aster::path() - .segment("__SerializeWith") - .with_generics(wrapper_generics.clone()) - .build() - .build(); - - quote!({ - struct __SerializeWith #wrapper_generics #where_clause { - value: &'__a #field_ty, - phantom: ::std::marker::PhantomData<#item_ty>, - } - - impl #wrapper_generics _serde::Serialize for #wrapper_ty #where_clause { - fn serialize<__S>(&self, __s: __S) -> _serde::export::Result<__S::Ok, __S::Error> - where __S: _serde::Serializer - { - #path(self.value, __s) - } - } - - &__SerializeWith { - value: #value, - phantom: ::std::marker::PhantomData::<#item_ty>, - } - }) -} - -// Serialization of an empty struct results in code like: -// -// let mut __serde_state = try!(serializer.serialize_struct("S", 0)); -// _serde::ser::SerializeStruct::end(__serde_state) -// -// where we want to omit the `mut` to avoid a warning. -fn mut_if(is_mut: bool) -> Option { - if is_mut { - Some(quote!(mut)) - } else { - None - } -} diff --git a/third_party/rust/serde_codegen_internals/.cargo-checksum.json b/third_party/rust/serde_codegen_internals/.cargo-checksum.json index 036d08d69c6e..3781538ae093 100644 --- a/third_party/rust/serde_codegen_internals/.cargo-checksum.json +++ b/third_party/rust/serde_codegen_internals/.cargo-checksum.json @@ -1 +1 @@ -{"files":{".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","Cargo.toml":"d95e5e29244853cb6c744f76f8829d6404fb517b69ea79c9b9f807ae0845c6c5","src/ast.rs":"0b96616b2becc71ac85ffb0efcf6c6d0b451c7e2e4934df19193962e7fc9316a","src/attr.rs":"f248f768cde166c5c9e2bb03335fc70148a0460e3434d3cb470ebb9ac41b3948","src/ctxt.rs":"80795ca96772fdef304584795966bbf28c24b788590c83e44efca3bb45a7d06a","src/lib.rs":"a5b9dae1488c7c50f5ed630bf473f5ca13d44f795faf380152fef10bfc7b9eee"},"package":"afad7924a009f859f380e4a2e3a509a845c2ac66435fcead74a4d983b21ae806"} \ No newline at end of file +{"files":{".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","Cargo.toml":"f11d07b974965dc94833195275fa536a0d7790e16ad3389d08f1e198202073fa","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"6485b8ed310d3f0340bf1ad1f47645069ce4069dcc6bb46c7d5c6faf41de1fdb","README.md":"ebe318a04cf4e547e0f3ab97f1345ecb553358ee13ea81f99e3323e37d70ccdf","src/ast.rs":"7eedebeb0d2b76bda66c0b414a2a40ac19ff1d8604a84cd5d207b76d2d57de97","src/attr.rs":"77daffa2fd682d85debac843c5e69ebf1a1061a680c5d8e590ecf8fcf63976b7","src/case.rs":"44e5506efb5a99478b357f1b2ee1baf40a44b8630997cd62d657b1c677752932","src/ctxt.rs":"3650e9cfc8b58e65137bc5e5ee250117c5abe4a543807a908adabf1a1f57825a","src/lib.rs":"e620949a156816b0e326481d1070febc449cf72849bffd3ca15c473ff3af13e8"},"package":"4d52006899f910528a10631e5b727973fe668f3228109d1707ccf5bad5490b6e"} \ No newline at end of file diff --git a/third_party/rust/serde_codegen_internals/Cargo.toml b/third_party/rust/serde_codegen_internals/Cargo.toml index f03cacd86fb1..439b9f12f922 100644 --- a/third_party/rust/serde_codegen_internals/Cargo.toml +++ b/third_party/rust/serde_codegen_internals/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "serde_codegen_internals" -version = "0.11.3" +version = "0.14.1" authors = ["Erick Tryzelaar "] license = "MIT/Apache-2.0" description = "AST representation used by Serde codegen. Unstable." @@ -8,11 +8,11 @@ homepage = "https://serde.rs" repository = "https://github.com/serde-rs/serde" documentation = "https://docs.serde.rs/serde_codegen_internals/" keywords = ["serde", "serialization"] -include = ["Cargo.toml", "src/**/*.rs"] - -[features] -unstable-testing = ["clippy"] +readme = "../README.md" +include = ["Cargo.toml", "src/**/*.rs", "README.md", "LICENSE-APACHE", "LICENSE-MIT"] [dependencies] -clippy = { version = "^0.*", optional = true } -syn = "0.10" +syn = { version = "0.11", default-features = false, features = ["parsing"] } + +[badges] +travis-ci = { repository = "serde-rs/serde" } diff --git a/third_party/rust/serde_codegen_internals/LICENSE-APACHE b/third_party/rust/serde_codegen_internals/LICENSE-APACHE new file mode 100644 index 000000000000..16fe87b06e80 --- /dev/null +++ b/third_party/rust/serde_codegen_internals/LICENSE-APACHE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright [yyyy] [name of copyright owner] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/third_party/rust/serde_codegen_internals/LICENSE-MIT b/third_party/rust/serde_codegen_internals/LICENSE-MIT new file mode 100644 index 000000000000..39d4bdb5acd3 --- /dev/null +++ b/third_party/rust/serde_codegen_internals/LICENSE-MIT @@ -0,0 +1,25 @@ +Copyright (c) 2014 The Rust Project Developers + +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. diff --git a/third_party/rust/serde_codegen_internals/README.md b/third_party/rust/serde_codegen_internals/README.md new file mode 100644 index 000000000000..9d568010bc0d --- /dev/null +++ b/third_party/rust/serde_codegen_internals/README.md @@ -0,0 +1,71 @@ +# Serde   [![Build Status](https://api.travis-ci.org/serde-rs/serde.svg?branch=master)](https://travis-ci.org/serde-rs/serde) [![Latest Version](https://img.shields.io/crates/v/serde.svg)](https://crates.io/crates/serde) + +**Serde is a framework for *ser*ializing and *de*serializing Rust data structures efficiently and generically.** + +--- + +You may be looking for: + +- [An overview of Serde](https://serde.rs/) +- [Data formats supported by Serde](https://serde.rs/#data-formats) +- [Setting up `#[derive(Serialize, Deserialize)]`](https://serde.rs/codegen.html) +- [Examples](https://serde.rs/examples.html) +- [API documentation](https://docs.serde.rs/serde/) +- [Release notes](https://github.com/serde-rs/serde/releases) + +## Serde in action + +```rust +#[macro_use] +extern crate serde_derive; + +extern crate serde_json; + +#[derive(Serialize, Deserialize, Debug)] +struct Point { + x: i32, + y: i32, +} + +fn main() { + let point = Point { x: 1, y: 2 }; + + // Convert the Point to a JSON string. + let serialized = serde_json::to_string(&point).unwrap(); + + // Prints serialized = {"x":1,"y":2} + println!("serialized = {}", serialized); + + // Convert the JSON string back to a Point. + let deserialized: Point = serde_json::from_str(&serialized).unwrap(); + + // Prints deserialized = Point { x: 1, y: 2 } + println!("deserialized = {:?}", deserialized); +} +``` + +## Getting help + +Serde developers live in the #serde channel on +[`irc.mozilla.org`](https://wiki.mozilla.org/IRC). The #rust channel is also a +good resource with generally faster response time but less specific knowledge +about Serde. If IRC is not your thing or you don't get a good response, we are +happy to respond to [GitHub issues](https://github.com/serde-rs/serde/issues/new) +as well. + +## License + +Serde is licensed under either of + + * Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or + http://www.apache.org/licenses/LICENSE-2.0) + * MIT license ([LICENSE-MIT](LICENSE-MIT) or + http://opensource.org/licenses/MIT) + +at your option. + +### Contribution + +Unless you explicitly state otherwise, any contribution intentionally submitted +for inclusion in Serde by you, as defined in the Apache-2.0 license, shall be +dual licensed as above, without any additional terms or conditions. diff --git a/third_party/rust/serde_codegen_internals/src/ast.rs b/third_party/rust/serde_codegen_internals/src/ast.rs index 2941c1641944..0a50691ebdf6 100644 --- a/third_party/rust/serde_codegen_internals/src/ast.rs +++ b/third_party/rust/serde_codegen_internals/src/ast.rs @@ -38,16 +38,30 @@ impl<'a> Item<'a> { pub fn from_ast(cx: &Ctxt, item: &'a syn::MacroInput) -> Item<'a> { let attrs = attr::Item::from_ast(cx, item); - let body = match item.body { - syn::Body::Enum(ref variants) => { - Body::Enum(enum_from_ast(cx, variants)) - } + let mut body = match item.body { + syn::Body::Enum(ref variants) => Body::Enum(enum_from_ast(cx, variants)), syn::Body::Struct(ref variant_data) => { let (style, fields) = struct_from_ast(cx, variant_data); Body::Struct(style, fields) } }; + match body { + Body::Enum(ref mut variants) => { + for ref mut variant in variants { + variant.attrs.rename_by_rule(attrs.rename_all()); + for ref mut field in &mut variant.fields { + field.attrs.rename_by_rule(variant.attrs.rename_all()); + } + } + } + Body::Struct(_, ref mut fields) => { + for field in fields { + field.attrs.rename_by_rule(attrs.rename_all()); + } + } + } + Item { ident: item.ident.clone(), attrs: attrs, @@ -58,15 +72,13 @@ impl<'a> Item<'a> { } impl<'a> Body<'a> { - pub fn all_fields(&'a self) -> Box> + 'a> { + pub fn all_fields(&'a self) -> Box> + 'a> { match *self { Body::Enum(ref variants) => { Box::new(variants.iter() - .flat_map(|variant| variant.fields.iter())) - } - Body::Struct(_, ref fields) => { - Box::new(fields.iter()) + .flat_map(|variant| variant.fields.iter())) } + Body::Struct(_, ref fields) => Box::new(fields.iter()), } } } @@ -87,18 +99,12 @@ fn enum_from_ast<'a>(cx: &Ctxt, variants: &'a [syn::Variant]) -> Vec fn struct_from_ast<'a>(cx: &Ctxt, data: &'a syn::VariantData) -> (Style, Vec>) { match *data { - syn::VariantData::Struct(ref fields) => { - (Style::Struct, fields_from_ast(cx, fields)) - } + syn::VariantData::Struct(ref fields) => (Style::Struct, fields_from_ast(cx, fields)), syn::VariantData::Tuple(ref fields) if fields.len() == 1 => { (Style::Newtype, fields_from_ast(cx, fields)) } - syn::VariantData::Tuple(ref fields) => { - (Style::Tuple, fields_from_ast(cx, fields)) - } - syn::VariantData::Unit => { - (Style::Unit, Vec::new()) - } + syn::VariantData::Tuple(ref fields) => (Style::Tuple, fields_from_ast(cx, fields)), + syn::VariantData::Unit => (Style::Unit, Vec::new()), } } diff --git a/third_party/rust/serde_codegen_internals/src/attr.rs b/third_party/rust/serde_codegen_internals/src/attr.rs index 632dd508db3c..92a183c4b8c7 100644 --- a/third_party/rust/serde_codegen_internals/src/attr.rs +++ b/third_party/rust/serde_codegen_internals/src/attr.rs @@ -2,6 +2,7 @@ use Ctxt; use syn; use syn::MetaItem::{List, NameValue, Word}; use syn::NestedMetaItem::{Literal, MetaItem}; +use std::str::FromStr; // This module handles parsing of `#[serde(...)]` attributes. The entrypoints // are `attr::Item::from_ast`, `attr::Variant::from_ast`, and @@ -11,6 +12,8 @@ use syn::NestedMetaItem::{Literal, MetaItem}; // user will see errors simultaneously for all bad attributes in the crate // rather than just the first. +pub use case::RenameRule; + struct Attr<'c, T> { cx: &'c Ctxt, name: &'static str, @@ -90,8 +93,43 @@ impl Name { pub struct Item { name: Name, deny_unknown_fields: bool, + default: Default, + rename_all: RenameRule, ser_bound: Option>, de_bound: Option>, + tag: EnumTag, +} + +/// Styles of representing an enum. +#[derive(Debug)] +pub enum EnumTag { + /// The default. + /// + /// ```json + /// {"variant1": {"key1": "value1", "key2": "value2"}} + /// ``` + External, + + /// `#[serde(tag = "type")]` + /// + /// ```json + /// {"type": "variant1", "key1": "value1", "key2": "value2"} + /// ``` + Internal { tag: String }, + + /// `#[serde(tag = "t", content = "c")]` + /// + /// ```json + /// {"t": "variant1", "c": {"key1": "value1", "key2": "value2"}} + /// ``` + Adjacent { tag: String, content: String }, + + /// `#[serde(untagged)]` + /// + /// ```json + /// {"key1": "value1", "key2": "value2"} + /// ``` + None, } impl Item { @@ -100,8 +138,13 @@ impl Item { let mut ser_name = Attr::none(cx, "rename"); let mut de_name = Attr::none(cx, "rename"); let mut deny_unknown_fields = BoolAttr::none(cx, "deny_unknown_fields"); + let mut default = Attr::none(cx, "default"); + let mut rename_all = Attr::none(cx, "rename_all"); let mut ser_bound = Attr::none(cx, "bound"); let mut de_bound = Attr::none(cx, "bound"); + let mut untagged = BoolAttr::none(cx, "untagged"); + let mut internal_tag = Attr::none(cx, "tag"); + let mut content = Attr::none(cx, "content"); for meta_items in item.attrs.iter().filter_map(get_serde_meta_items) { for meta_item in meta_items { @@ -122,14 +165,57 @@ impl Item { } } + // Parse `#[serde(rename_all="foo")]` + MetaItem(NameValue(ref name, ref lit)) if name == "rename_all" => { + if let Ok(s) = get_string_from_lit(cx, name.as_ref(), name.as_ref(), lit) { + match RenameRule::from_str(&s) { + Ok(rename_rule) => rename_all.set(rename_rule), + Err(()) => { + cx.error(format!("unknown rename rule for #[serde(rename_all \ + = {:?})]", + s)) + } + } + } + } + // Parse `#[serde(deny_unknown_fields)]` MetaItem(Word(ref name)) if name == "deny_unknown_fields" => { deny_unknown_fields.set_true(); } + // Parse `#[serde(default)]` + MetaItem(Word(ref name)) if name == "default" => { + match item.body { + syn::Body::Struct(syn::VariantData::Struct(_)) => { + default.set(Default::Default); + } + _ => { + cx.error("#[serde(default)] can only be used on structs \ + with named fields") + } + } + } + + // Parse `#[serde(default="...")]` + MetaItem(NameValue(ref name, ref lit)) if name == "default" => { + if let Ok(path) = parse_lit_into_path(cx, name.as_ref(), lit) { + match item.body { + syn::Body::Struct(syn::VariantData::Struct(_)) => { + default.set(Default::Path(path)); + } + _ => { + cx.error("#[serde(default = \"...\")] can only be used \ + on structs with named fields") + } + } + } + } + // Parse `#[serde(bound="D: Serialize")]` MetaItem(NameValue(ref name, ref lit)) if name == "bound" => { - if let Ok(where_predicates) = parse_lit_into_where(cx, name.as_ref(), name.as_ref(), lit) { + if let Ok(where_predicates) = + parse_lit_into_where(cx, name.as_ref(), name.as_ref(), lit) { ser_bound.set(where_predicates.clone()); de_bound.set(where_predicates); } @@ -143,26 +229,116 @@ impl Item { } } + // Parse `#[serde(untagged)]` + MetaItem(Word(ref name)) if name == "untagged" => { + match item.body { + syn::Body::Enum(_) => { + untagged.set_true(); + } + syn::Body::Struct(_) => { + cx.error("#[serde(untagged)] can only be used on enums") + } + } + } + + // Parse `#[serde(tag = "type")]` + MetaItem(NameValue(ref name, ref lit)) if name == "tag" => { + if let Ok(s) = get_string_from_lit(cx, name.as_ref(), name.as_ref(), lit) { + match item.body { + syn::Body::Enum(_) => { + internal_tag.set(s); + } + syn::Body::Struct(_) => { + cx.error("#[serde(tag = \"...\")] can only be used on enums") + } + } + } + } + + // Parse `#[serde(content = "c")]` + MetaItem(NameValue(ref name, ref lit)) if name == "content" => { + if let Ok(s) = get_string_from_lit(cx, name.as_ref(), name.as_ref(), lit) { + match item.body { + syn::Body::Enum(_) => { + content.set(s); + } + syn::Body::Struct(_) => { + cx.error("#[serde(content = \"...\")] can only be used on \ + enums") + } + } + } + } + MetaItem(ref meta_item) => { cx.error(format!("unknown serde container attribute `{}`", meta_item.name())); } Literal(_) => { - cx.error(format!("unexpected literal in serde container attribute")); + cx.error("unexpected literal in serde container attribute"); } } } } + let tag = match (untagged.get(), internal_tag.get(), content.get()) { + (false, None, None) => EnumTag::External, + (true, None, None) => EnumTag::None, + (false, Some(tag), None) => { + // Check that there are no tuple variants. + if let syn::Body::Enum(ref variants) = item.body { + for variant in variants { + match variant.data { + syn::VariantData::Struct(_) | + syn::VariantData::Unit => {} + syn::VariantData::Tuple(ref fields) => { + if fields.len() != 1 { + cx.error("#[serde(tag = \"...\")] cannot be used with tuple \ + variants"); + break; + } + } + } + } + } + EnumTag::Internal { tag: tag } + } + (true, Some(_), None) => { + cx.error("enum cannot be both untagged and internally tagged"); + EnumTag::External // doesn't matter, will error + } + (false, None, Some(_)) => { + cx.error("#[serde(tag = \"...\", content = \"...\")] must be used together"); + EnumTag::External + } + (true, None, Some(_)) => { + cx.error("untagged enum cannot have #[serde(content = \"...\")]"); + EnumTag::External + } + (false, Some(tag), Some(content)) => { + EnumTag::Adjacent { + tag: tag, + content: content, + } + } + (true, Some(_), Some(_)) => { + cx.error("untagged enum cannot have #[serde(tag = \"...\", content = \"...\")]"); + EnumTag::External + } + }; + Item { name: Name { serialize: ser_name.get().unwrap_or_else(|| item.ident.to_string()), deserialize: de_name.get().unwrap_or_else(|| item.ident.to_string()), }, deny_unknown_fields: deny_unknown_fields.get(), + default: default.get().unwrap_or(Default::None), + rename_all: rename_all.get().unwrap_or(RenameRule::None), ser_bound: ser_bound.get(), de_bound: de_bound.get(), + tag: tag, } } @@ -170,10 +346,18 @@ impl Item { &self.name } + pub fn rename_all(&self) -> &RenameRule { + &self.rename_all + } + pub fn deny_unknown_fields(&self) -> bool { self.deny_unknown_fields } + pub fn default(&self) -> &Default { + &self.default + } + pub fn ser_bound(&self) -> Option<&[syn::WherePredicate]> { self.ser_bound.as_ref().map(|vec| &vec[..]) } @@ -181,12 +365,19 @@ impl Item { pub fn de_bound(&self) -> Option<&[syn::WherePredicate]> { self.de_bound.as_ref().map(|vec| &vec[..]) } + + pub fn tag(&self) -> &EnumTag { + &self.tag + } } /// Represents variant attribute information #[derive(Debug)] pub struct Variant { name: Name, + ser_renamed: bool, + de_renamed: bool, + rename_all: RenameRule, skip_deserializing: bool, skip_serializing: bool, } @@ -197,6 +388,7 @@ impl Variant { let mut de_name = Attr::none(cx, "rename"); let mut skip_deserializing = BoolAttr::none(cx, "skip_deserializing"); let mut skip_serializing = BoolAttr::none(cx, "skip_serializing"); + let mut rename_all = Attr::none(cx, "rename_all"); for meta_items in variant.attrs.iter().filter_map(get_serde_meta_items) { for meta_item in meta_items { @@ -216,6 +408,21 @@ impl Variant { de_name.set_opt(de); } } + + // Parse `#[serde(rename_all="foo")]` + MetaItem(NameValue(ref name, ref lit)) if name == "rename_all" => { + if let Ok(s) = get_string_from_lit(cx, name.as_ref(), name.as_ref(), lit) { + match RenameRule::from_str(&s) { + Ok(rename_rule) => rename_all.set(rename_rule), + Err(()) => { + cx.error(format!("unknown rename rule for #[serde(rename_all \ + = {:?})]", + s)) + } + } + } + } + // Parse `#[serde(skip_deserializing)]` MetaItem(Word(ref name)) if name == "skip_deserializing" => { skip_deserializing.set_true(); @@ -226,22 +433,28 @@ impl Variant { } MetaItem(ref meta_item) => { - cx.error(format!("unknown serde variant attribute `{}`", - meta_item.name())); + cx.error(format!("unknown serde variant attribute `{}`", meta_item.name())); } Literal(_) => { - cx.error(format!("unexpected literal in serde variant attribute")); + cx.error("unexpected literal in serde variant attribute"); } } } } + let ser_name = ser_name.get(); + let ser_renamed = ser_name.is_some(); + let de_name = de_name.get(); + let de_renamed = de_name.is_some(); Variant { name: Name { - serialize: ser_name.get().unwrap_or_else(|| variant.ident.to_string()), - deserialize: de_name.get().unwrap_or_else(|| variant.ident.to_string()), + serialize: ser_name.unwrap_or_else(|| variant.ident.to_string()), + deserialize: de_name.unwrap_or_else(|| variant.ident.to_string()), }, + ser_renamed: ser_renamed, + de_renamed: de_renamed, + rename_all: rename_all.get().unwrap_or(RenameRule::None), skip_deserializing: skip_deserializing.get(), skip_serializing: skip_serializing.get(), } @@ -251,6 +464,19 @@ impl Variant { &self.name } + pub fn rename_by_rule(&mut self, rule: &RenameRule) { + if !self.ser_renamed { + self.name.serialize = rule.apply_to_variant(&self.name.serialize); + } + if !self.de_renamed { + self.name.deserialize = rule.apply_to_variant(&self.name.deserialize); + } + } + + pub fn rename_all(&self) -> &RenameRule { + &self.rename_all + } + pub fn skip_deserializing(&self) -> bool { self.skip_deserializing } @@ -264,10 +490,12 @@ impl Variant { #[derive(Debug)] pub struct Field { name: Name, + ser_renamed: bool, + de_renamed: bool, skip_serializing: bool, skip_deserializing: bool, skip_serializing_if: Option, - default: FieldDefault, + default: Default, serialize_with: Option, deserialize_with: Option, ser_bound: Option>, @@ -276,7 +504,7 @@ pub struct Field { /// Represents the default to use for a field when deserializing. #[derive(Debug, PartialEq)] -pub enum FieldDefault { +pub enum Default { /// Field must always be specified because it does not have a default. None, /// The default is given by `std::default::Default::default()`. @@ -287,9 +515,7 @@ pub enum FieldDefault { impl Field { /// Extract out the `#[serde(...)]` attributes from a struct field. - pub fn from_ast(cx: &Ctxt, - index: usize, - field: &syn::Field) -> Self { + pub fn from_ast(cx: &Ctxt, index: usize, field: &syn::Field) -> Self { let mut ser_name = Attr::none(cx, "rename"); let mut de_name = Attr::none(cx, "rename"); let mut skip_serializing = BoolAttr::none(cx, "skip_serializing"); @@ -327,13 +553,13 @@ impl Field { // Parse `#[serde(default)]` MetaItem(Word(ref name)) if name == "default" => { - default.set(FieldDefault::Default); + default.set(Default::Default); } // Parse `#[serde(default="...")]` MetaItem(NameValue(ref name, ref lit)) if name == "default" => { if let Ok(path) = parse_lit_into_path(cx, name.as_ref(), lit) { - default.set(FieldDefault::Path(path)); + default.set(Default::Path(path)); } } @@ -368,9 +594,22 @@ impl Field { } } + // Parse `#[serde(with="...")]` + MetaItem(NameValue(ref name, ref lit)) if name == "with" => { + if let Ok(path) = parse_lit_into_path(cx, name.as_ref(), lit) { + let mut ser_path = path.clone(); + ser_path.segments.push("serialize".into()); + serialize_with.set(ser_path); + let mut de_path = path; + de_path.segments.push("deserialize".into()); + deserialize_with.set(de_path); + } + } + // Parse `#[serde(bound="D: Serialize")]` MetaItem(NameValue(ref name, ref lit)) if name == "bound" => { - if let Ok(where_predicates) = parse_lit_into_where(cx, name.as_ref(), name.as_ref(), lit) { + if let Ok(where_predicates) = + parse_lit_into_where(cx, name.as_ref(), name.as_ref(), lit) { ser_bound.set(where_predicates.clone()); de_bound.set(where_predicates); } @@ -385,12 +624,11 @@ impl Field { } MetaItem(ref meta_item) => { - cx.error(format!("unknown serde field attribute `{}`", - meta_item.name())); + cx.error(format!("unknown serde field attribute `{}`", meta_item.name())); } Literal(_) => { - cx.error(format!("unexpected literal in serde field attribute")); + cx.error("unexpected literal in serde field attribute"); } } } @@ -399,18 +637,24 @@ impl Field { // Is skip_deserializing, initialize the field to Default::default() // unless a different default is specified by `#[serde(default="...")]` if skip_deserializing.0.value.is_some() { - default.set_if_none(FieldDefault::Default); + default.set_if_none(Default::Default); } + let ser_name = ser_name.get(); + let ser_renamed = ser_name.is_some(); + let de_name = de_name.get(); + let de_renamed = de_name.is_some(); Field { name: Name { - serialize: ser_name.get().unwrap_or(ident.clone()), - deserialize: de_name.get().unwrap_or(ident), + serialize: ser_name.unwrap_or_else(|| ident.clone()), + deserialize: de_name.unwrap_or(ident), }, + ser_renamed: ser_renamed, + de_renamed: de_renamed, skip_serializing: skip_serializing.get(), skip_deserializing: skip_deserializing.get(), skip_serializing_if: skip_serializing_if.get(), - default: default.get().unwrap_or(FieldDefault::None), + default: default.get().unwrap_or(Default::None), serialize_with: serialize_with.get(), deserialize_with: deserialize_with.get(), ser_bound: ser_bound.get(), @@ -422,6 +666,15 @@ impl Field { &self.name } + pub fn rename_by_rule(&mut self, rule: &RenameRule) { + if !self.ser_renamed { + self.name.serialize = rule.apply_to_field(&self.name.serialize); + } + if !self.de_renamed { + self.name.deserialize = rule.apply_to_field(&self.name.deserialize); + } + } + pub fn skip_serializing(&self) -> bool { self.skip_serializing } @@ -434,7 +687,7 @@ impl Field { self.skip_serializing_if.as_ref() } - pub fn default(&self) -> &FieldDefault { + pub fn default(&self) -> &Default { &self.default } @@ -457,13 +710,12 @@ impl Field { type SerAndDe = (Option, Option); -fn get_ser_and_de( - cx: &Ctxt, - attr_name: &'static str, - items: &[syn::NestedMetaItem], - f: F -) -> Result, ()> - where F: Fn(&Ctxt, &str, &str, &syn::Lit) -> Result, +fn get_ser_and_de(cx: &Ctxt, + attr_name: &'static str, + items: &[syn::NestedMetaItem], + f: F) + -> Result, ()> + where F: Fn(&Ctxt, &str, &str, &syn::Lit) -> Result { let mut ser_item = Attr::none(cx, attr_name); let mut de_item = Attr::none(cx, attr_name); @@ -483,7 +735,8 @@ fn get_ser_and_de( } _ => { - cx.error(format!("malformed {0} attribute, expected `{0}(serialize = ..., deserialize = ...)`", + cx.error(format!("malformed {0} attribute, expected `{0}(serialize = ..., \ + deserialize = ...)`", attr_name)); return Err(()); } @@ -493,35 +746,34 @@ fn get_ser_and_de( Ok((ser_item.get(), de_item.get())) } -fn get_renames( - cx: &Ctxt, - items: &[syn::NestedMetaItem], -) -> Result, ()> { +fn get_renames(cx: &Ctxt, items: &[syn::NestedMetaItem]) -> Result, ()> { get_ser_and_de(cx, "rename", items, get_string_from_lit) } -fn get_where_predicates( - cx: &Ctxt, - items: &[syn::NestedMetaItem], -) -> Result>, ()> { +fn get_where_predicates(cx: &Ctxt, + items: &[syn::NestedMetaItem]) + -> Result>, ()> { get_ser_and_de(cx, "bound", items, parse_lit_into_where) } pub fn get_serde_meta_items(attr: &syn::Attribute) -> Option> { match attr.value { - List(ref name, ref items) if name == "serde" => { - Some(items.iter().cloned().collect()) - } - _ => None + List(ref name, ref items) if name == "serde" => Some(items.iter().cloned().collect()), + _ => None, } } -fn get_string_from_lit(cx: &Ctxt, attr_name: &str, meta_item_name: &str, lit: &syn::Lit) -> Result { +fn get_string_from_lit(cx: &Ctxt, + attr_name: &str, + meta_item_name: &str, + lit: &syn::Lit) + -> Result { if let syn::Lit::Str(ref s, _) = *lit { Ok(s.clone()) } else { cx.error(format!("expected serde {} attribute to be a string: `{} = \"...\"`", - attr_name, meta_item_name)); + attr_name, + meta_item_name)); Err(()) } } @@ -531,7 +783,11 @@ fn parse_lit_into_path(cx: &Ctxt, attr_name: &str, lit: &syn::Lit) -> Result Result, ()> { +fn parse_lit_into_where(cx: &Ctxt, + attr_name: &str, + meta_item_name: &str, + lit: &syn::Lit) + -> Result, ()> { let string = try!(get_string_from_lit(cx, attr_name, meta_item_name, lit)); if string.is_empty() { return Ok(Vec::new()); diff --git a/third_party/rust/serde_codegen_internals/src/case.rs b/third_party/rust/serde_codegen_internals/src/case.rs new file mode 100644 index 000000000000..d25d98df424a --- /dev/null +++ b/third_party/rust/serde_codegen_internals/src/case.rs @@ -0,0 +1,115 @@ +use std::ascii::AsciiExt; +use std::str::FromStr; + +use self::RenameRule::*; + +#[derive(Debug, PartialEq)] +pub enum RenameRule { + /// Don't apply a default rename rule. + None, + /// Rename direct children to "PascalCase" style, as typically used for enum variants. + PascalCase, + /// Rename direct children to "camelCase" style. + CamelCase, + /// Rename direct children to "snake_case" style, as commonly used for fields. + SnakeCase, + /// Rename direct children to "SCREAMING_SNAKE_CASE" style, as commonly used for constants. + ScreamingSnakeCase, + /// Rename direct children to "kebab-case" style. + KebabCase, +} + +impl RenameRule { + pub fn apply_to_variant(&self, variant: &str) -> String { + match *self { + None | PascalCase => variant.to_owned(), + CamelCase => variant[..1].to_ascii_lowercase() + &variant[1..], + SnakeCase => { + let mut snake = String::new(); + for (i, ch) in variant.char_indices() { + if i > 0 && ch.is_uppercase() { + snake.push('_'); + } + snake.push(ch.to_ascii_lowercase()); + } + snake + } + ScreamingSnakeCase => SnakeCase.apply_to_variant(variant).to_ascii_uppercase(), + KebabCase => SnakeCase.apply_to_variant(variant).replace('_', "-"), + } + } + + pub fn apply_to_field(&self, field: &str) -> String { + match *self { + None | SnakeCase => field.to_owned(), + PascalCase => { + let mut pascal = String::new(); + let mut capitalize = true; + for ch in field.chars() { + if ch == '_' { + capitalize = true; + } else if capitalize { + pascal.push(ch.to_ascii_uppercase()); + capitalize = false; + } else { + pascal.push(ch); + } + } + pascal + } + CamelCase => { + let pascal = PascalCase.apply_to_field(field); + pascal[..1].to_ascii_lowercase() + &pascal[1..] + } + ScreamingSnakeCase => field.to_ascii_uppercase(), + KebabCase => field.replace('_', "-"), + } + } +} + +impl FromStr for RenameRule { + type Err = (); + + fn from_str(rename_all_str: &str) -> Result { + match rename_all_str { + "PascalCase" => Ok(PascalCase), + "camelCase" => Ok(CamelCase), + "snake_case" => Ok(SnakeCase), + "SCREAMING_SNAKE_CASE" => Ok(ScreamingSnakeCase), + "kebab-case" => Ok(KebabCase), + _ => Err(()), + } + } +} + +#[test] +fn rename_variants() { + for &(original, camel, snake, screaming, kebab) in + &[("Outcome", "outcome", "outcome", "OUTCOME", "outcome"), + ("VeryTasty", "veryTasty", "very_tasty", "VERY_TASTY", "very-tasty"), + ("A", "a", "a", "A", "a"), + ("Z42", "z42", "z42", "Z42", "z42")] { + assert_eq!(None.apply_to_variant(original), original); + assert_eq!(PascalCase.apply_to_variant(original), original); + assert_eq!(CamelCase.apply_to_variant(original), camel); + assert_eq!(SnakeCase.apply_to_variant(original), snake); + assert_eq!(ScreamingSnakeCase.apply_to_variant(original), screaming); + assert_eq!(KebabCase.apply_to_variant(original), kebab); + } +} + +#[test] +fn rename_fields() { + for &(original, pascal, camel, screaming, kebab) in + &[("outcome", "Outcome", "outcome", "OUTCOME", "outcome"), + ("very_tasty", "VeryTasty", "veryTasty", "VERY_TASTY", "very-tasty"), + ("a", "A", "a", "A", "a"), + ("z42", "Z42", "z42", "Z42", "z42")] { + assert_eq!(None.apply_to_field(original), original); + assert_eq!(PascalCase.apply_to_field(original), pascal); + assert_eq!(CamelCase.apply_to_field(original), camel); + assert_eq!(SnakeCase.apply_to_field(original), original); + assert_eq!(ScreamingSnakeCase.apply_to_field(original), screaming); + assert_eq!(KebabCase.apply_to_field(original), kebab); + } +} diff --git a/third_party/rust/serde_codegen_internals/src/ctxt.rs b/third_party/rust/serde_codegen_internals/src/ctxt.rs index a1455332cae2..a112c7e969b8 100644 --- a/third_party/rust/serde_codegen_internals/src/ctxt.rs +++ b/third_party/rust/serde_codegen_internals/src/ctxt.rs @@ -8,9 +8,7 @@ pub struct Ctxt { impl Ctxt { pub fn new() -> Self { - Ctxt { - errors: RefCell::new(Some(Vec::new())), - } + Ctxt { errors: RefCell::new(Some(Vec::new())) } } pub fn error(&self, msg: T) { diff --git a/third_party/rust/serde_codegen_internals/src/lib.rs b/third_party/rust/serde_codegen_internals/src/lib.rs index 0f37f5fa2df2..c5e8885c71c6 100644 --- a/third_party/rust/serde_codegen_internals/src/lib.rs +++ b/third_party/rust/serde_codegen_internals/src/lib.rs @@ -1,6 +1,3 @@ -#![cfg_attr(feature = "clippy", plugin(clippy))] -#![cfg_attr(feature = "clippy", feature(plugin))] - extern crate syn; pub mod ast; @@ -8,3 +5,5 @@ pub mod attr; mod ctxt; pub use ctxt::Ctxt; + +mod case; diff --git a/third_party/rust/serde_derive/.cargo-checksum.json b/third_party/rust/serde_derive/.cargo-checksum.json new file mode 100644 index 000000000000..73e118e34464 --- /dev/null +++ b/third_party/rust/serde_derive/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","Cargo.toml":"b48eda1c232a1fb0725482abbe38616d3e9df3ba207c6581b2c918b6976cdcbf","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"6485b8ed310d3f0340bf1ad1f47645069ce4069dcc6bb46c7d5c6faf41de1fdb","README.md":"ebe318a04cf4e547e0f3ab97f1345ecb553358ee13ea81f99e3323e37d70ccdf","src/bound.rs":"9af80108627e7065366bd065e5125fbf292a3aac4e4014977decc42f659d3af2","src/de.rs":"51cedf6f6711b90829cb625f0e43ed765380321e1add80646cda3561dfe3d074","src/fragment.rs":"a4d5286453b280d457579bd17b4deb3f9ce2e5f6c3e446c4ef61774b87045589","src/lib.rs":"53826d40b094cb4c39d5b99dcc4ce1f84e96cec8d7e51e158b00036d18c7442a","src/ser.rs":"19aab089d33b23e46805b5d58185b1471b6d2ede5fe5f272767ce95ff1d48a31"},"package":"f15ea24bd037b2d64646b4d934fa99c649be66e3f7b29fb595a5543b212b1452"} \ No newline at end of file diff --git a/third_party/rust/servo-dwrote/.cargo-ok b/third_party/rust/serde_derive/.cargo-ok similarity index 100% rename from third_party/rust/servo-dwrote/.cargo-ok rename to third_party/rust/serde_derive/.cargo-ok diff --git a/third_party/rust/serde_derive/Cargo.toml b/third_party/rust/serde_derive/Cargo.toml new file mode 100644 index 000000000000..433f6b9b33fa --- /dev/null +++ b/third_party/rust/serde_derive/Cargo.toml @@ -0,0 +1,27 @@ +[package] +name = "serde_derive" +version = "0.9.11" +authors = ["Erick Tryzelaar "] +license = "MIT/Apache-2.0" +description = "Macros 1.1 implementation of #[derive(Serialize, Deserialize)]" +homepage = "https://serde.rs" +repository = "https://github.com/serde-rs/serde" +documentation = "https://serde.rs/codegen.html" +keywords = ["serde", "serialization", "no_std"] +readme = "../README.md" +include = ["Cargo.toml", "src/**/*.rs", "README.md", "LICENSE-APACHE", "LICENSE-MIT"] + +[features] +unstable = [] + +[badges] +travis-ci = { repository = "serde-rs/serde" } + +[lib] +name = "serde_derive" +proc-macro = true + +[dependencies] +quote = "0.3.8" +serde_codegen_internals = { version = "=0.14.1", default-features = false, path = "../serde_codegen_internals" } +syn = { version = "0.11", features = ["visit"] } diff --git a/third_party/rust/serde_derive/LICENSE-APACHE b/third_party/rust/serde_derive/LICENSE-APACHE new file mode 100644 index 000000000000..16fe87b06e80 --- /dev/null +++ b/third_party/rust/serde_derive/LICENSE-APACHE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright [yyyy] [name of copyright owner] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/third_party/rust/serde_derive/LICENSE-MIT b/third_party/rust/serde_derive/LICENSE-MIT new file mode 100644 index 000000000000..39d4bdb5acd3 --- /dev/null +++ b/third_party/rust/serde_derive/LICENSE-MIT @@ -0,0 +1,25 @@ +Copyright (c) 2014 The Rust Project Developers + +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. diff --git a/third_party/rust/serde_derive/README.md b/third_party/rust/serde_derive/README.md new file mode 100644 index 000000000000..9d568010bc0d --- /dev/null +++ b/third_party/rust/serde_derive/README.md @@ -0,0 +1,71 @@ +# Serde   [![Build Status](https://api.travis-ci.org/serde-rs/serde.svg?branch=master)](https://travis-ci.org/serde-rs/serde) [![Latest Version](https://img.shields.io/crates/v/serde.svg)](https://crates.io/crates/serde) + +**Serde is a framework for *ser*ializing and *de*serializing Rust data structures efficiently and generically.** + +--- + +You may be looking for: + +- [An overview of Serde](https://serde.rs/) +- [Data formats supported by Serde](https://serde.rs/#data-formats) +- [Setting up `#[derive(Serialize, Deserialize)]`](https://serde.rs/codegen.html) +- [Examples](https://serde.rs/examples.html) +- [API documentation](https://docs.serde.rs/serde/) +- [Release notes](https://github.com/serde-rs/serde/releases) + +## Serde in action + +```rust +#[macro_use] +extern crate serde_derive; + +extern crate serde_json; + +#[derive(Serialize, Deserialize, Debug)] +struct Point { + x: i32, + y: i32, +} + +fn main() { + let point = Point { x: 1, y: 2 }; + + // Convert the Point to a JSON string. + let serialized = serde_json::to_string(&point).unwrap(); + + // Prints serialized = {"x":1,"y":2} + println!("serialized = {}", serialized); + + // Convert the JSON string back to a Point. + let deserialized: Point = serde_json::from_str(&serialized).unwrap(); + + // Prints deserialized = Point { x: 1, y: 2 } + println!("deserialized = {:?}", deserialized); +} +``` + +## Getting help + +Serde developers live in the #serde channel on +[`irc.mozilla.org`](https://wiki.mozilla.org/IRC). The #rust channel is also a +good resource with generally faster response time but less specific knowledge +about Serde. If IRC is not your thing or you don't get a good response, we are +happy to respond to [GitHub issues](https://github.com/serde-rs/serde/issues/new) +as well. + +## License + +Serde is licensed under either of + + * Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or + http://www.apache.org/licenses/LICENSE-2.0) + * MIT license ([LICENSE-MIT](LICENSE-MIT) or + http://opensource.org/licenses/MIT) + +at your option. + +### Contribution + +Unless you explicitly state otherwise, any contribution intentionally submitted +for inclusion in Serde by you, as defined in the Apache-2.0 license, shall be +dual licensed as above, without any additional terms or conditions. diff --git a/third_party/rust/serde_derive/src/bound.rs b/third_party/rust/serde_derive/src/bound.rs new file mode 100644 index 000000000000..2fe797a1d5f6 --- /dev/null +++ b/third_party/rust/serde_derive/src/bound.rs @@ -0,0 +1,228 @@ +use std::collections::HashSet; + +use syn::{self, visit}; + +use internals::ast::Item; +use internals::attr; + +macro_rules! path { + ($first:ident $(:: $rest:ident)*) => { + syn::Path { + global: false, + segments: vec![ + stringify!($first).into(), + $( + stringify!($rest).into(), + )* + ], + } + }; + + (::$first:ident $(:: $rest:ident)*) => { + syn::Path { + global: true, + segments: vec![ + stringify!($first).into(), + $( + stringify!($rest).into(), + )* + ], + } + }; +} + +// Remove the default from every type parameter because in the generated impls +// they look like associated types: "error: associated type bindings are not +// allowed here". +pub fn without_defaults(generics: &syn::Generics) -> syn::Generics { + syn::Generics { + ty_params: generics.ty_params + .iter() + .map(|ty_param| syn::TyParam { default: None, ..ty_param.clone() }) + .collect(), + ..generics.clone() + } +} + +pub fn with_where_predicates(generics: &syn::Generics, + predicates: &[syn::WherePredicate]) + -> syn::Generics { + let mut generics = generics.clone(); + generics.where_clause.predicates.extend_from_slice(predicates); + generics +} + +pub fn with_where_predicates_from_fields(item: &Item, + generics: &syn::Generics, + from_field: F) + -> syn::Generics + where F: Fn(&attr::Field) -> Option<&[syn::WherePredicate]> +{ + let predicates = item.body + .all_fields() + .flat_map(|field| from_field(&field.attrs)) + .flat_map(|predicates| predicates.to_vec()); + + let mut generics = generics.clone(); + generics.where_clause.predicates.extend(predicates); + generics +} + +// Puts the given bound on any generic type parameters that are used in fields +// for which filter returns true. +// +// For example, the following struct needs the bound `A: Serialize, B: Serialize`. +// +// struct S<'b, A, B: 'b, C> { +// a: A, +// b: Option<&'b B> +// #[serde(skip_serializing)] +// c: C, +// } +pub fn with_bound(item: &Item, + generics: &syn::Generics, + filter: F, + bound: &syn::Path) + -> syn::Generics + where F: Fn(&attr::Field) -> bool +{ + struct FindTyParams { + // Set of all generic type parameters on the current struct (A, B, C in + // the example). Initialized up front. + all_ty_params: HashSet, + // Set of generic type parameters used in fields for which filter + // returns true (A and B in the example). Filled in as the visitor sees + // them. + relevant_ty_params: HashSet, + } + impl visit::Visitor for FindTyParams { + fn visit_path(&mut self, path: &syn::Path) { + if let Some(seg) = path.segments.last() { + if seg.ident == "PhantomData" { + // Hardcoded exception, because PhantomData implements + // Serialize and Deserialize whether or not T implements it. + return; + } + } + if !path.global && path.segments.len() == 1 { + let id = path.segments[0].ident.clone(); + if self.all_ty_params.contains(&id) { + self.relevant_ty_params.insert(id); + } + } + visit::walk_path(self, path); + } + } + + let all_ty_params: HashSet<_> = generics.ty_params + .iter() + .map(|ty_param| ty_param.ident.clone()) + .collect(); + + let relevant_tys = item.body + .all_fields() + .filter(|&field| filter(&field.attrs)) + .map(|field| &field.ty); + + let mut visitor = FindTyParams { + all_ty_params: all_ty_params, + relevant_ty_params: HashSet::new(), + }; + for ty in relevant_tys { + visit::walk_ty(&mut visitor, ty); + } + + let new_predicates = generics.ty_params + .iter() + .map(|ty_param| ty_param.ident.clone()) + .filter(|id| visitor.relevant_ty_params.contains(id)) + .map(|id| { + syn::WherePredicate::BoundPredicate(syn::WhereBoundPredicate { + bound_lifetimes: Vec::new(), + // the type parameter that is being bounded e.g. T + bounded_ty: syn::Ty::Path(None, id.into()), + // the bound e.g. Serialize + bounds: vec![syn::TyParamBound::Trait( + syn::PolyTraitRef { + bound_lifetimes: Vec::new(), + trait_ref: bound.clone(), + }, + syn::TraitBoundModifier::None + )], + }) + }); + + let mut generics = generics.clone(); + generics.where_clause.predicates.extend(new_predicates); + generics +} + +pub fn with_self_bound(item: &Item, + generics: &syn::Generics, + bound: &syn::Path) + -> syn::Generics +{ + let mut generics = generics.clone(); + generics.where_clause.predicates.push( + syn::WherePredicate::BoundPredicate(syn::WhereBoundPredicate { + bound_lifetimes: Vec::new(), + // the type that is being bounded e.g. MyStruct<'a, T> + bounded_ty: type_of_item(item), + // the bound e.g. Default + bounds: vec![syn::TyParamBound::Trait( + syn::PolyTraitRef { + bound_lifetimes: Vec::new(), + trait_ref: bound.clone(), + }, + syn::TraitBoundModifier::None + )], + }) + ); + generics +} + +pub fn with_lifetime_bound(generics: &syn::Generics, + lifetime: &str) + -> syn::Generics { + let mut generics = generics.clone(); + + for lifetime_def in &mut generics.lifetimes { + lifetime_def.bounds.push(syn::Lifetime::new(lifetime)); + } + + for ty_param in &mut generics.ty_params { + ty_param.bounds.push(syn::TyParamBound::Region(syn::Lifetime::new(lifetime))); + } + + generics.lifetimes.push(syn::LifetimeDef { + attrs: Vec::new(), + lifetime: syn::Lifetime::new(lifetime), + bounds: Vec::new(), + }); + + generics +} + +fn type_of_item(item: &Item) -> syn::Ty { + syn::Ty::Path(None, syn::Path { + global: false, + segments: vec![ + syn::PathSegment { + ident: item.ident.clone(), + parameters: syn::PathParameters::AngleBracketed(syn::AngleBracketedParameterData { + lifetimes: item.generics + .lifetimes + .iter() + .map(|def| def.lifetime.clone()) + .collect(), + types: item.generics + .ty_params + .iter() + .map(|param| syn::Ty::Path(None, param.ident.clone().into())) + .collect(), + bindings: Vec::new(), + }), + } + ] + }) +} diff --git a/third_party/rust/serde_derive/src/de.rs b/third_party/rust/serde_derive/src/de.rs new file mode 100644 index 000000000000..b47f334bdde1 --- /dev/null +++ b/third_party/rust/serde_derive/src/de.rs @@ -0,0 +1,1404 @@ +use syn::{self, Ident}; +use quote::{self, Tokens}; + +use bound; +use fragment::{Fragment, Expr, Stmts, Match}; +use internals::ast::{Body, Field, Item, Style, Variant}; +use internals::{self, attr}; + +pub fn expand_derive_deserialize(item: &syn::DeriveInput) -> Result { + let item = { + let ctxt = internals::Ctxt::new(); + let item = Item::from_ast(&ctxt, item); + check_no_str(&ctxt, &item); + try!(ctxt.check()); + item + }; + + let ident = &item.ident; + let generics = build_generics(&item); + let (impl_generics, ty_generics, where_clause) = generics.split_for_impl(); + let dummy_const = Ident::new(format!("_IMPL_DESERIALIZE_FOR_{}", ident)); + let body = Stmts(deserialize_body(&item, &generics)); + + Ok(quote! { + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + const #dummy_const: () = { + extern crate serde as _serde; + #[automatically_derived] + impl #impl_generics _serde::Deserialize for #ident #ty_generics #where_clause { + fn deserialize<__D>(deserializer: __D) -> _serde::export::Result + where __D: _serde::Deserializer + { + #body + } + } + }; + }) +} + +// All the generics in the input, plus a bound `T: Deserialize` for each generic +// field type that will be deserialized by us, plus a bound `T: Default` for +// each generic field type that will be set to a default value. +fn build_generics(item: &Item) -> syn::Generics { + let generics = bound::without_defaults(item.generics); + + let generics = + bound::with_where_predicates_from_fields(item, &generics, attr::Field::de_bound); + + match item.attrs.de_bound() { + Some(predicates) => bound::with_where_predicates(&generics, predicates), + None => { + let generics = match *item.attrs.default() { + attr::Default::Default => { + bound::with_self_bound(item, &generics, &path!(_serde::export::Default)) + } + attr::Default::None | attr::Default::Path(_) => generics, + }; + + let generics = + bound::with_bound(item, + &generics, + needs_deserialize_bound, + &path!(_serde::Deserialize)); + + bound::with_bound(item, + &generics, + requires_default, + &path!(_serde::export::Default)) + } + } +} + +// Fields with a `skip_deserializing` or `deserialize_with` attribute are not +// deserialized by us so we do not generate a bound. Fields with a `bound` +// attribute specify their own bound so we do not generate one. All other fields +// may need a `T: Deserialize` bound where T is the type of the field. +fn needs_deserialize_bound(attrs: &attr::Field) -> bool { + !attrs.skip_deserializing() && attrs.deserialize_with().is_none() && attrs.de_bound().is_none() +} + +// Fields with a `default` attribute (not `default=...`), and fields with a +// `skip_deserializing` attribute that do not also have `default=...`. +fn requires_default(attrs: &attr::Field) -> bool { + attrs.default() == &attr::Default::Default +} + +fn deserialize_body(item: &Item, generics: &syn::Generics) -> Fragment { + match item.body { + Body::Enum(ref variants) => { + deserialize_item_enum(&item.ident, generics, variants, &item.attrs) + } + Body::Struct(Style::Struct, ref fields) => { + if fields.iter().any(|field| field.ident.is_none()) { + panic!("struct has unnamed fields"); + } + + deserialize_struct(&item.ident, + None, + generics, + fields, + &item.attrs, + None) + } + Body::Struct(Style::Tuple, ref fields) | + Body::Struct(Style::Newtype, ref fields) => { + if fields.iter().any(|field| field.ident.is_some()) { + panic!("tuple struct has named fields"); + } + + deserialize_tuple(&item.ident, + None, + generics, + fields, + &item.attrs, + None) + } + Body::Struct(Style::Unit, _) => deserialize_unit_struct(&item.ident, &item.attrs), + } +} + +fn deserialize_unit_struct(ident: &syn::Ident, item_attrs: &attr::Item) -> Fragment { + let type_name = item_attrs.name().deserialize_name(); + + let expecting = format!("unit struct {}", ident); + + quote_block! { + struct __Visitor; + + impl _serde::de::Visitor for __Visitor { + type Value = #ident; + + fn expecting(&self, formatter: &mut _serde::export::fmt::Formatter) -> _serde::export::fmt::Result { + _serde::export::fmt::Formatter::write_str(formatter, #expecting) + } + + #[inline] + fn visit_unit<__E>(self) -> _serde::export::Result<#ident, __E> + where __E: _serde::de::Error, + { + _serde::export::Ok(#ident) + } + + #[inline] + fn visit_seq<__V>(self, _: __V) -> _serde::export::Result<#ident, __V::Error> + where __V: _serde::de::SeqVisitor, + { + _serde::export::Ok(#ident) + } + } + + deserializer.deserialize_unit_struct(#type_name, __Visitor) + } +} + +fn deserialize_tuple(ident: &syn::Ident, + variant_ident: Option<&syn::Ident>, + generics: &syn::Generics, + fields: &[Field], + item_attrs: &attr::Item, + deserializer: Option) + -> Fragment { + let (impl_generics, ty_generics, where_clause) = generics.split_for_impl(); + + let is_enum = variant_ident.is_some(); + let type_path = match variant_ident { + Some(variant_ident) => quote!(#ident::#variant_ident), + None => quote!(#ident), + }; + let expecting = match variant_ident { + Some(variant_ident) => format!("tuple variant {}::{}", ident, variant_ident), + None => format!("tuple struct {}", ident), + }; + + let nfields = fields.len(); + + let visit_newtype_struct = if !is_enum && nfields == 1 { + Some(deserialize_newtype_struct(ident, &type_path, generics, &fields[0])) + } else { + None + }; + + let visit_seq = Stmts(deserialize_seq(ident, &type_path, generics, fields, false, item_attrs)); + + let visitor_expr = quote! { + __Visitor { marker: _serde::export::PhantomData::<#ident #ty_generics> } + }; + let dispatch = if let Some(deserializer) = deserializer { + quote!(_serde::Deserializer::deserialize_tuple(#deserializer, #nfields, #visitor_expr)) + } else if is_enum { + quote!(_serde::de::VariantVisitor::visit_tuple(visitor, #nfields, #visitor_expr)) + } else if nfields == 1 { + let type_name = item_attrs.name().deserialize_name(); + quote!(_serde::Deserializer::deserialize_newtype_struct(deserializer, #type_name, #visitor_expr)) + } else { + let type_name = item_attrs.name().deserialize_name(); + quote!(_serde::Deserializer::deserialize_tuple_struct(deserializer, #type_name, #nfields, #visitor_expr)) + }; + + let all_skipped = fields.iter().all(|field| field.attrs.skip_deserializing()); + let visitor_var = if all_skipped { + quote!(_) + } else { + quote!(mut visitor) + }; + + quote_block! { + struct __Visitor #impl_generics #where_clause { + marker: _serde::export::PhantomData<#ident #ty_generics>, + } + + impl #impl_generics _serde::de::Visitor for __Visitor #ty_generics #where_clause { + type Value = #ident #ty_generics; + + fn expecting(&self, formatter: &mut _serde::export::fmt::Formatter) -> _serde::export::fmt::Result { + _serde::export::fmt::Formatter::write_str(formatter, #expecting) + } + + #visit_newtype_struct + + #[inline] + fn visit_seq<__V>(self, #visitor_var: __V) -> _serde::export::Result + where __V: _serde::de::SeqVisitor + { + #visit_seq + } + } + + #dispatch + } +} + +fn deserialize_seq(ident: &syn::Ident, + type_path: &Tokens, + generics: &syn::Generics, + fields: &[Field], + is_struct: bool, + item_attrs: &attr::Item) + -> Fragment { + let vars = (0..fields.len()).map(field_i as fn(_) -> _); + + let deserialized_count = fields.iter() + .filter(|field| !field.attrs.skip_deserializing()) + .count(); + let expecting = format!("tuple of {} elements", deserialized_count); + + let mut index_in_seq = 0usize; + let let_values = vars.clone().zip(fields) + .map(|(var, field)| { + if field.attrs.skip_deserializing() { + let default = Expr(expr_is_missing(&field, item_attrs)); + quote! { + let #var = #default; + } + } else { + let visit = match field.attrs.deserialize_with() { + None => { + let field_ty = &field.ty; + quote!(try!(_serde::de::SeqVisitor::visit::<#field_ty>(&mut visitor))) + } + Some(path) => { + let (wrapper, wrapper_ty) = wrap_deserialize_with( + ident, generics, field.ty, path); + quote!({ + #wrapper + try!(_serde::de::SeqVisitor::visit::<#wrapper_ty>(&mut visitor)) + .map(|wrap| wrap.value) + }) + } + }; + let assign = quote! { + let #var = match #visit { + Some(value) => { value }, + None => { + return _serde::export::Err(_serde::de::Error::invalid_length(#index_in_seq, &#expecting)); + } + }; + }; + index_in_seq += 1; + assign + } + }); + + let result = if is_struct { + let names = fields.iter().map(|f| &f.ident); + quote! { + #type_path { #( #names: #vars ),* } + } + } else { + quote! { + #type_path ( #(#vars),* ) + } + }; + + quote_block! { + #(#let_values)* + _serde::export::Ok(#result) + } +} + +fn deserialize_newtype_struct(ident: &syn::Ident, + type_path: &Tokens, + generics: &syn::Generics, + field: &Field) + -> Tokens { + let value = match field.attrs.deserialize_with() { + None => { + let field_ty = &field.ty; + quote! { + try!(<#field_ty as _serde::Deserialize>::deserialize(__e)) + } + } + Some(path) => { + let (wrapper, wrapper_ty) = + wrap_deserialize_with(ident, generics, field.ty, path); + quote!({ + #wrapper + try!(<#wrapper_ty as _serde::Deserialize>::deserialize(__e)).value + }) + } + }; + quote! { + #[inline] + fn visit_newtype_struct<__E>(self, __e: __E) -> _serde::export::Result + where __E: _serde::Deserializer, + { + _serde::export::Ok(#type_path(#value)) + } + } +} + +fn deserialize_struct(ident: &syn::Ident, + variant_ident: Option<&syn::Ident>, + generics: &syn::Generics, + fields: &[Field], + item_attrs: &attr::Item, + deserializer: Option) + -> Fragment { + let is_enum = variant_ident.is_some(); + let is_untagged = deserializer.is_some(); + + let (impl_generics, ty_generics, where_clause) = generics.split_for_impl(); + + let type_path = match variant_ident { + Some(variant_ident) => quote!(#ident::#variant_ident), + None => quote!(#ident), + }; + let expecting = match variant_ident { + Some(variant_ident) => format!("struct variant {}::{}", ident, variant_ident), + None => format!("struct {}", ident), + }; + + let visit_seq = Stmts(deserialize_seq(ident, &type_path, generics, fields, true, item_attrs)); + + let (field_visitor, fields_stmt, visit_map) = + deserialize_struct_visitor(ident, type_path, generics, fields, item_attrs); + let field_visitor = Stmts(field_visitor); + let fields_stmt = Stmts(fields_stmt); + let visit_map = Stmts(visit_map); + + let visitor_expr = quote! { + __Visitor { marker: _serde::export::PhantomData::<#ident #ty_generics> } + }; + let dispatch = if let Some(deserializer) = deserializer { + quote! { + _serde::Deserializer::deserialize(#deserializer, #visitor_expr) + } + } else if is_enum { + quote! { + _serde::de::VariantVisitor::visit_struct(visitor, FIELDS, #visitor_expr) + } + } else { + let type_name = item_attrs.name().deserialize_name(); + quote! { + _serde::Deserializer::deserialize_struct(deserializer, #type_name, FIELDS, #visitor_expr) + } + }; + + let all_skipped = fields.iter().all(|field| field.attrs.skip_deserializing()); + let visitor_var = if all_skipped { + quote!(_) + } else { + quote!(mut visitor) + }; + + let visit_seq = if is_untagged { + // untagged struct variants do not get a visit_seq method + None + } else { + Some(quote! { + #[inline] + fn visit_seq<__V>(self, #visitor_var: __V) -> _serde::export::Result + where __V: _serde::de::SeqVisitor + { + #visit_seq + } + }) + }; + + quote_block! { + #field_visitor + + struct __Visitor #impl_generics #where_clause { + marker: _serde::export::PhantomData<#ident #ty_generics>, + } + + impl #generics _serde::de::Visitor for __Visitor #ty_generics #where_clause { + type Value = #ident #ty_generics; + + fn expecting(&self, formatter: &mut _serde::export::fmt::Formatter) -> _serde::export::fmt::Result { + _serde::export::fmt::Formatter::write_str(formatter, #expecting) + } + + #visit_seq + + #[inline] + fn visit_map<__V>(self, mut visitor: __V) -> _serde::export::Result + where __V: _serde::de::MapVisitor + { + #visit_map + } + } + + #fields_stmt + + #dispatch + } +} + +fn deserialize_item_enum(ident: &syn::Ident, + generics: &syn::Generics, + variants: &[Variant], + item_attrs: &attr::Item) + -> Fragment { + match *item_attrs.tag() { + attr::EnumTag::External => { + deserialize_externally_tagged_enum(ident, generics, variants, item_attrs) + } + attr::EnumTag::Internal { ref tag } => { + deserialize_internally_tagged_enum(ident, + generics, + variants, + item_attrs, + tag) + } + attr::EnumTag::Adjacent { ref tag, ref content } => { + deserialize_adjacently_tagged_enum(ident, + generics, + variants, + item_attrs, + tag, + content) + } + attr::EnumTag::None => { + deserialize_untagged_enum(ident, generics, variants, item_attrs) + } + } +} + +fn deserialize_externally_tagged_enum(ident: &syn::Ident, + generics: &syn::Generics, + variants: &[Variant], + item_attrs: &attr::Item) + -> Fragment { + let (impl_generics, ty_generics, where_clause) = generics.split_for_impl(); + + let type_name = item_attrs.name().deserialize_name(); + + let expecting = format!("enum {}", ident); + + let variant_names_idents: Vec<_> = variants.iter() + .enumerate() + .filter(|&(_, variant)| !variant.attrs.skip_deserializing()) + .map(|(i, variant)| (variant.attrs.name().deserialize_name(), field_i(i))) + .collect(); + + let variants_stmt = { + let variant_names = variant_names_idents.iter().map(|&(ref name, _)| name); + quote! { + const VARIANTS: &'static [&'static str] = &[ #(#variant_names),* ]; + } + }; + + let variant_visitor = Stmts(deserialize_field_visitor(variant_names_idents, item_attrs, true)); + + // Match arms to extract a variant from a string + let variant_arms = variants.iter() + .enumerate() + .filter(|&(_, variant)| !variant.attrs.skip_deserializing()) + .map(|(i, variant)| { + let variant_name = field_i(i); + + let block = Match(deserialize_externally_tagged_variant(ident, + generics, + variant, + item_attrs)); + + quote! { + (__Field::#variant_name, visitor) => #block + } + }); + + let all_skipped = variants.iter().all(|variant| variant.attrs.skip_deserializing()); + let match_variant = if all_skipped { + // This is an empty enum like `enum Impossible {}` or an enum in which + // all variants have `#[serde(skip_deserializing)]`. + quote! { + // FIXME: Once we drop support for Rust 1.15: + // let _serde::export::Err(err) = _serde::de::EnumVisitor::visit_variant::<__Field>(visitor); + // _serde::export::Err(err) + _serde::de::EnumVisitor::visit_variant::<__Field>(visitor) + .map(|(impossible, _)| match impossible {}) + } + } else { + quote! { + match try!(_serde::de::EnumVisitor::visit_variant(visitor)) { + #(#variant_arms)* + } + } + }; + + quote_block! { + #variant_visitor + + struct __Visitor #impl_generics #where_clause { + marker: _serde::export::PhantomData<#ident #ty_generics>, + } + + impl #generics _serde::de::Visitor for __Visitor #ty_generics #where_clause { + type Value = #ident #ty_generics; + + fn expecting(&self, formatter: &mut _serde::export::fmt::Formatter) -> _serde::export::fmt::Result { + _serde::export::fmt::Formatter::write_str(formatter, #expecting) + } + + fn visit_enum<__V>(self, visitor: __V) -> _serde::export::Result + where __V: _serde::de::EnumVisitor, + { + #match_variant + } + } + + #variants_stmt + + _serde::Deserializer::deserialize_enum(deserializer, #type_name, VARIANTS, + __Visitor { + marker: _serde::export::PhantomData::<#ident #ty_generics>, + }) + } +} + +fn deserialize_internally_tagged_enum(ident: &syn::Ident, + generics: &syn::Generics, + variants: &[Variant], + item_attrs: &attr::Item, + tag: &str) + -> Fragment { + let variant_names_idents: Vec<_> = variants.iter() + .enumerate() + .filter(|&(_, variant)| !variant.attrs.skip_deserializing()) + .map(|(i, variant)| (variant.attrs.name().deserialize_name(), field_i(i))) + .collect(); + + let variants_stmt = { + let variant_names = variant_names_idents.iter().map(|&(ref name, _)| name); + quote! { + const VARIANTS: &'static [&'static str] = &[ #(#variant_names),* ]; + } + }; + + let variant_visitor = Stmts(deserialize_field_visitor(variant_names_idents, item_attrs, true)); + + // Match arms to extract a variant from a string + let variant_arms = variants.iter() + .enumerate() + .filter(|&(_, variant)| !variant.attrs.skip_deserializing()) + .map(|(i, variant)| { + let variant_name = field_i(i); + + let block = Match(deserialize_internally_tagged_variant( + ident, + generics, + variant, + item_attrs, + quote!(_serde::de::private::ContentDeserializer::<__D::Error>::new(_tagged.content)), + )); + + quote! { + __Field::#variant_name => #block + } + }); + + quote_block! { + #variant_visitor + + #variants_stmt + + let _tagged = try!(_serde::Deserializer::deserialize( + deserializer, + _serde::de::private::TaggedContentVisitor::<__Field>::new(#tag))); + + match _tagged.tag { + #(#variant_arms)* + } + } +} + +fn deserialize_adjacently_tagged_enum(ident: &syn::Ident, + generics: &syn::Generics, + variants: &[Variant], + item_attrs: &attr::Item, + tag: &str, + content: &str) + -> Fragment { + let (impl_generics, ty_generics, where_clause) = generics.split_for_impl(); + + let variant_names_idents: Vec<_> = variants.iter() + .enumerate() + .filter(|&(_, variant)| !variant.attrs.skip_deserializing()) + .map(|(i, variant)| (variant.attrs.name().deserialize_name(), field_i(i))) + .collect(); + + let variants_stmt = { + let variant_names = variant_names_idents.iter().map(|&(ref name, _)| name); + quote! { + const VARIANTS: &'static [&'static str] = &[ #(#variant_names),* ]; + } + }; + + let variant_visitor = Stmts(deserialize_field_visitor(variant_names_idents, item_attrs, true)); + + let ref variant_arms: Vec<_> = variants.iter() + .enumerate() + .filter(|&(_, variant)| !variant.attrs.skip_deserializing()) + .map(|(i, variant)| { + let variant_index = field_i(i); + + let block = Match(deserialize_untagged_variant( + ident, + generics, + variant, + item_attrs, + quote!(_deserializer), + )); + + quote! { + __Field::#variant_index => #block + } + }) + .collect(); + + let expecting = format!("adjacently tagged enum {}", ident); + let type_name = item_attrs.name().deserialize_name(); + + let tag_or_content = quote! { + _serde::de::private::TagOrContentFieldVisitor { + tag: #tag, + content: #content, + } + }; + + fn is_unit(variant: &Variant) -> bool { + match variant.style { + Style::Unit => true, + Style::Struct | Style::Tuple | Style::Newtype => false, + } + } + + let mut missing_content = quote! { + _serde::export::Err(<__V::Error as _serde::de::Error>::missing_field(#content)) + }; + if variants.iter().any(is_unit) { + let fallthrough = if variants.iter().all(is_unit) { + None + } else { + Some(quote! { + _ => #missing_content + }) + }; + let arms = variants.iter() + .enumerate() + .filter(|&(_, variant)| !variant.attrs.skip_deserializing() && is_unit(variant)) + .map(|(i, variant)| { + let variant_index = field_i(i); + let variant_ident = &variant.ident; + quote! { + __Field::#variant_index => _serde::export::Ok(#ident::#variant_ident), + } + }); + missing_content = quote! { + match __field { + #(#arms)* + #fallthrough + } + }; + } + + let visit_third_key = quote! { + // Visit the third key in the map, hopefully there isn't one. + match try!(_serde::de::MapVisitor::visit_key_seed(&mut visitor, #tag_or_content)) { + _serde::export::Some(_serde::de::private::TagOrContentField::Tag) => { + _serde::export::Err(<__V::Error as _serde::de::Error>::duplicate_field(#tag)) + } + _serde::export::Some(_serde::de::private::TagOrContentField::Content) => { + _serde::export::Err(<__V::Error as _serde::de::Error>::duplicate_field(#content)) + } + _serde::export::None => _serde::export::Ok(__ret), + } + }; + + quote_block! { + #variant_visitor + + #variants_stmt + + struct __Seed #impl_generics #where_clause { + field: __Field, + marker: _serde::export::PhantomData<#ident #ty_generics>, + } + + impl #impl_generics _serde::de::DeserializeSeed for __Seed #ty_generics #where_clause { + type Value = #ident #ty_generics; + + fn deserialize<__D>(self, _deserializer: __D) -> _serde::export::Result + where __D: _serde::Deserializer + { + match self.field { + #(#variant_arms)* + } + } + } + + struct __Visitor #impl_generics #where_clause { + marker: _serde::export::PhantomData<#ident #ty_generics>, + } + + impl #impl_generics _serde::de::Visitor for __Visitor #ty_generics #where_clause { + type Value = #ident #ty_generics; + + fn expecting(&self, formatter: &mut _serde::export::fmt::Formatter) -> _serde::export::fmt::Result { + _serde::export::fmt::Formatter::write_str(formatter, #expecting) + } + + fn visit_map<__V>(self, mut visitor: __V) -> _serde::export::Result + where __V: _serde::de::MapVisitor + { + // Visit the first key. + match try!(_serde::de::MapVisitor::visit_key_seed(&mut visitor, #tag_or_content)) { + // First key is the tag. + _serde::export::Some(_serde::de::private::TagOrContentField::Tag) => { + // Parse the tag. + let __field = try!(_serde::de::MapVisitor::visit_value(&mut visitor)); + // Visit the second key. + match try!(_serde::de::MapVisitor::visit_key_seed(&mut visitor, #tag_or_content)) { + // Second key is a duplicate of the tag. + _serde::export::Some(_serde::de::private::TagOrContentField::Tag) => { + _serde::export::Err(<__V::Error as _serde::de::Error>::duplicate_field(#tag)) + } + // Second key is the content. + _serde::export::Some(_serde::de::private::TagOrContentField::Content) => { + let __ret = try!(_serde::de::MapVisitor::visit_value_seed(&mut visitor, __Seed { field: __field, marker: _serde::export::PhantomData })); + // Visit the third key, hopefully there isn't one. + #visit_third_key + } + // There is no second key; might be okay if the we have a unit variant. + _serde::export::None => #missing_content + } + } + // First key is the content. + _serde::export::Some(_serde::de::private::TagOrContentField::Content) => { + // Buffer up the content. + let __content = try!(_serde::de::MapVisitor::visit_value::<_serde::de::private::Content>(&mut visitor)); + // Visit the second key. + match try!(_serde::de::MapVisitor::visit_key_seed(&mut visitor, #tag_or_content)) { + // Second key is the tag. + _serde::export::Some(_serde::de::private::TagOrContentField::Tag) => { + let _deserializer = _serde::de::private::ContentDeserializer::<__V::Error>::new(__content); + // Parse the tag. + let __ret = try!(match try!(_serde::de::MapVisitor::visit_value(&mut visitor)) { + // Deserialize the buffered content now that we know the variant. + #(#variant_arms)* + }); + // Visit the third key, hopefully there isn't one. + #visit_third_key + } + // Second key is a duplicate of the content. + _serde::export::Some(_serde::de::private::TagOrContentField::Content) => { + _serde::export::Err(<__V::Error as _serde::de::Error>::duplicate_field(#content)) + } + // There is no second key. + _serde::export::None => { + _serde::export::Err(<__V::Error as _serde::de::Error>::missing_field(#tag)) + } + } + } + // There is no first key. + _serde::export::None => { + _serde::export::Err(<__V::Error as _serde::de::Error>::missing_field(#tag)) + } + } + } + + fn visit_seq<__V>(self, mut visitor: __V) -> _serde::export::Result + where __V: _serde::de::SeqVisitor + { + // Visit the first element - the tag. + match try!(_serde::de::SeqVisitor::visit(&mut visitor)) { + _serde::export::Some(__field) => { + // Visit the second element - the content. + match try!(_serde::de::SeqVisitor::visit_seed(&mut visitor, __Seed { field: __field, marker: _serde::export::PhantomData })) { + _serde::export::Some(__ret) => _serde::export::Ok(__ret), + // There is no second element. + _serde::export::None => { + _serde::export::Err(_serde::de::Error::invalid_length(1, &self)) + } + } + } + // There is no first element. + _serde::export::None => { + _serde::export::Err(_serde::de::Error::invalid_length(0, &self)) + } + } + } + } + + const FIELDS: &'static [&'static str] = &[#tag, #content]; + _serde::Deserializer::deserialize_struct(deserializer, #type_name, FIELDS, + __Visitor { marker: _serde::export::PhantomData::<#ident #ty_generics> }) + } +} + +fn deserialize_untagged_enum(ident: &syn::Ident, + generics: &syn::Generics, + variants: &[Variant], + item_attrs: &attr::Item) + -> Fragment { + let attempts = variants.iter() + .filter(|variant| !variant.attrs.skip_deserializing()) + .map(|variant| { + Expr(deserialize_untagged_variant( + ident, + generics, + variant, + item_attrs, + quote!(_serde::de::private::ContentRefDeserializer::<__D::Error>::new(&_content)), + )) + }); + + // TODO this message could be better by saving the errors from the failed + // attempts. The heuristic used by TOML was to count the number of fields + // processed before an error, and use the error that happened after the + // largest number of fields. I'm not sure I like that. Maybe it would be + // better to save all the errors and combine them into one message that + // explains why none of the variants matched. + let fallthrough_msg = format!("data did not match any variant of untagged enum {}", ident); + + quote_block! { + let _content = try!(<_serde::de::private::Content as _serde::Deserialize>::deserialize(deserializer)); + + #( + if let _serde::export::Ok(ok) = #attempts { + return _serde::export::Ok(ok); + } + )* + + _serde::export::Err(_serde::de::Error::custom(#fallthrough_msg)) + } +} + +fn deserialize_externally_tagged_variant(ident: &syn::Ident, + generics: &syn::Generics, + variant: &Variant, + item_attrs: &attr::Item) + -> Fragment { + let variant_ident = &variant.ident; + + match variant.style { + Style::Unit => { + quote_block! { + try!(_serde::de::VariantVisitor::visit_unit(visitor)); + _serde::export::Ok(#ident::#variant_ident) + } + } + Style::Newtype => { + deserialize_externally_tagged_newtype_variant(ident, + variant_ident, + generics, + &variant.fields[0]) + } + Style::Tuple => { + deserialize_tuple(ident, + Some(variant_ident), + generics, + &variant.fields, + item_attrs, + None) + } + Style::Struct => { + deserialize_struct(ident, + Some(variant_ident), + generics, + &variant.fields, + item_attrs, + None) + } + } +} + +fn deserialize_internally_tagged_variant(ident: &syn::Ident, + generics: &syn::Generics, + variant: &Variant, + item_attrs: &attr::Item, + deserializer: Tokens) + -> Fragment { + let variant_ident = &variant.ident; + + match variant.style { + Style::Unit => { + let type_name = ident.as_ref(); + let variant_name = variant.ident.as_ref(); + quote_block! { + try!(_serde::Deserializer::deserialize(#deserializer, _serde::de::private::InternallyTaggedUnitVisitor::new(#type_name, #variant_name))); + _serde::export::Ok(#ident::#variant_ident) + } + } + Style::Newtype | Style::Struct => { + deserialize_untagged_variant(ident, + generics, + variant, + item_attrs, + deserializer) + } + Style::Tuple => unreachable!("checked in serde_codegen_internals"), + } +} + +fn deserialize_untagged_variant(ident: &syn::Ident, + generics: &syn::Generics, + variant: &Variant, + item_attrs: &attr::Item, + deserializer: Tokens) + -> Fragment { + let variant_ident = &variant.ident; + + match variant.style { + Style::Unit => { + let type_name = ident.as_ref(); + let variant_name = variant.ident.as_ref(); + quote_expr! { + _serde::export::Result::map( + _serde::Deserializer::deserialize( + #deserializer, + _serde::de::private::UntaggedUnitVisitor::new(#type_name, #variant_name) + ), + |()| #ident::#variant_ident) + } + } + Style::Newtype => { + deserialize_untagged_newtype_variant(ident, + variant_ident, + generics, + &variant.fields[0], + deserializer) + } + Style::Tuple => { + deserialize_tuple(ident, + Some(variant_ident), + generics, + &variant.fields, + item_attrs, + Some(deserializer)) + } + Style::Struct => { + deserialize_struct(ident, + Some(variant_ident), + generics, + &variant.fields, + item_attrs, + Some(deserializer)) + } + } +} + +fn deserialize_externally_tagged_newtype_variant(ident: &syn::Ident, + variant_ident: &syn::Ident, + generics: &syn::Generics, + field: &Field) + -> Fragment { + match field.attrs.deserialize_with() { + None => { + let field_ty = &field.ty; + quote_expr! { + _serde::export::Result::map( + _serde::de::VariantVisitor::visit_newtype::<#field_ty>(visitor), + #ident::#variant_ident) + } + } + Some(path) => { + let (wrapper, wrapper_ty) = + wrap_deserialize_with(ident, generics, field.ty, path); + quote_block! { + #wrapper + _serde::export::Result::map( + _serde::de::VariantVisitor::visit_newtype::<#wrapper_ty>(visitor), + |_wrapper| #ident::#variant_ident(_wrapper.value)) + } + } + } +} + +fn deserialize_untagged_newtype_variant(ident: &syn::Ident, + variant_ident: &syn::Ident, + generics: &syn::Generics, + field: &Field, + deserializer: Tokens) + -> Fragment { + match field.attrs.deserialize_with() { + None => { + let field_ty = &field.ty; + quote_expr! { + _serde::export::Result::map( + <#field_ty as _serde::Deserialize>::deserialize(#deserializer), + #ident::#variant_ident) + } + } + Some(path) => { + let (wrapper, wrapper_ty) = + wrap_deserialize_with(ident, generics, field.ty, path); + quote_block! { + #wrapper + _serde::export::Result::map( + <#wrapper_ty as _serde::Deserialize>::deserialize(#deserializer), + |_wrapper| #ident::#variant_ident(_wrapper.value)) + } + } + } +} + +fn deserialize_field_visitor(fields: Vec<(String, Ident)>, + item_attrs: &attr::Item, + is_variant: bool) + -> Fragment { + let field_strs = fields.iter().map(|&(ref name, _)| name); + let field_bytes = fields.iter().map(|&(ref name, _)| quote::ByteStr(name)); + let field_idents: &Vec<_> = &fields.iter().map(|&(_, ref ident)| ident).collect(); + + let ignore_variant = if is_variant || item_attrs.deny_unknown_fields() { + None + } else { + Some(quote!(__ignore,)) + }; + + let visit_index = if is_variant { + let variant_indices = 0u32..; + let fallthrough_msg = format!("variant index 0 <= i < {}", fields.len()); + Some(quote! { + fn visit_u32<__E>(self, value: u32) -> _serde::export::Result<__Field, __E> + where __E: _serde::de::Error + { + match value { + #( + #variant_indices => _serde::export::Ok(__Field::#field_idents), + )* + _ => _serde::export::Err(_serde::de::Error::invalid_value( + _serde::de::Unexpected::Unsigned(value as u64), + &#fallthrough_msg)) + } + } + }) + } else { + None + }; + + let fallthrough_arm = if is_variant { + quote! { + _serde::export::Err(_serde::de::Error::unknown_variant(value, VARIANTS)) + } + } else if item_attrs.deny_unknown_fields() { + quote! { + _serde::export::Err(_serde::de::Error::unknown_field(value, FIELDS)) + } + } else { + quote! { + _serde::export::Ok(__Field::__ignore) + } + }; + + let bytes_to_str = if is_variant || item_attrs.deny_unknown_fields() { + Some(quote! { + let value = &_serde::export::from_utf8_lossy(value); + }) + } else { + None + }; + + quote_block! { + #[allow(non_camel_case_types)] + enum __Field { + #(#field_idents,)* + #ignore_variant + } + + impl _serde::Deserialize for __Field { + #[inline] + fn deserialize<__D>(deserializer: __D) -> _serde::export::Result<__Field, __D::Error> + where __D: _serde::Deserializer, + { + struct __FieldVisitor; + + impl _serde::de::Visitor for __FieldVisitor { + type Value = __Field; + + fn expecting(&self, formatter: &mut _serde::export::fmt::Formatter) -> _serde::export::fmt::Result { + _serde::export::fmt::Formatter::write_str(formatter, "field name") + } + + #visit_index + + fn visit_str<__E>(self, value: &str) -> _serde::export::Result<__Field, __E> + where __E: _serde::de::Error + { + match value { + #( + #field_strs => _serde::export::Ok(__Field::#field_idents), + )* + _ => #fallthrough_arm + } + } + + fn visit_bytes<__E>(self, value: &[u8]) -> _serde::export::Result<__Field, __E> + where __E: _serde::de::Error + { + match value { + #( + #field_bytes => _serde::export::Ok(__Field::#field_idents), + )* + _ => { + #bytes_to_str + #fallthrough_arm + } + } + } + } + + _serde::Deserializer::deserialize_struct_field(deserializer, __FieldVisitor) + } + } + } +} + +fn deserialize_struct_visitor(ident: &syn::Ident, + struct_path: Tokens, + generics: &syn::Generics, + fields: &[Field], + item_attrs: &attr::Item) + -> (Fragment, Fragment, Fragment) { + let field_names_idents: Vec<_> = fields.iter() + .enumerate() + .filter(|&(_, field)| !field.attrs.skip_deserializing()) + .map(|(i, field)| (field.attrs.name().deserialize_name(), field_i(i))) + .collect(); + + let fields_stmt = { + let field_names = field_names_idents.iter().map(|&(ref name, _)| name); + quote_block! { + const FIELDS: &'static [&'static str] = &[ #(#field_names),* ]; + } + }; + + let field_visitor = deserialize_field_visitor(field_names_idents, item_attrs, false); + + let visit_map = deserialize_map(ident, struct_path, generics, fields, item_attrs); + + (field_visitor, fields_stmt, visit_map) +} + +fn deserialize_map(ident: &syn::Ident, + struct_path: Tokens, + generics: &syn::Generics, + fields: &[Field], + item_attrs: &attr::Item) + -> Fragment { + // Create the field names for the fields. + let fields_names: Vec<_> = fields.iter() + .enumerate() + .map(|(i, field)| (field, field_i(i))) + .collect(); + + // Declare each field that will be deserialized. + let let_values = fields_names.iter() + .filter(|&&(field, _)| !field.attrs.skip_deserializing()) + .map(|&(field, ref name)| { + let field_ty = &field.ty; + quote! { + let mut #name: _serde::export::Option<#field_ty> = _serde::export::None; + } + }); + + // Match arms to extract a value for a field. + let value_arms = fields_names.iter() + .filter(|&&(field, _)| !field.attrs.skip_deserializing()) + .map(|&(field, ref name)| { + let deser_name = field.attrs.name().deserialize_name(); + + let visit = match field.attrs.deserialize_with() { + None => { + let field_ty = &field.ty; + quote! { + try!(_serde::de::MapVisitor::visit_value::<#field_ty>(&mut visitor)) + } + } + Some(path) => { + let (wrapper, wrapper_ty) = wrap_deserialize_with( + ident, generics, field.ty, path); + quote!({ + #wrapper + try!(_serde::de::MapVisitor::visit_value::<#wrapper_ty>(&mut visitor)).value + }) + } + }; + quote! { + __Field::#name => { + if _serde::export::Option::is_some(&#name) { + return _serde::export::Err(<__V::Error as _serde::de::Error>::duplicate_field(#deser_name)); + } + #name = _serde::export::Some(#visit); + } + } + }); + + // Visit ignored values to consume them + let ignored_arm = if item_attrs.deny_unknown_fields() { + None + } else { + Some(quote! { + _ => { let _ = try!(_serde::de::MapVisitor::visit_value::<_serde::de::impls::IgnoredAny>(&mut visitor)); } + }) + }; + + let all_skipped = fields.iter().all(|field| field.attrs.skip_deserializing()); + let match_keys = if item_attrs.deny_unknown_fields() && all_skipped { + quote! { + // FIXME: Once we drop support for Rust 1.15: + // let _serde::export::None::<__Field> = try!(_serde::de::MapVisitor::visit_key(&mut visitor)); + try!(_serde::de::MapVisitor::visit_key::<__Field>(&mut visitor)) + .map(|impossible| match impossible {}); + } + } else { + quote! { + while let _serde::export::Some(key) = try!(_serde::de::MapVisitor::visit_key::<__Field>(&mut visitor)) { + match key { + #(#value_arms)* + #ignored_arm + } + } + } + }; + + let extract_values = fields_names.iter() + .filter(|&&(field, _)| !field.attrs.skip_deserializing()) + .map(|&(field, ref name)| { + let missing_expr = Match(expr_is_missing(&field, item_attrs)); + + quote! { + let #name = match #name { + _serde::export::Some(#name) => #name, + _serde::export::None => #missing_expr + }; + } + }); + + let result = fields_names.iter() + .map(|&(field, ref name)| { + let ident = field.ident.clone().expect("struct contains unnamed fields"); + if field.attrs.skip_deserializing() { + let value = Expr(expr_is_missing(&field, item_attrs)); + quote!(#ident: #value) + } else { + quote!(#ident: #name) + } + }); + + let let_default = match *item_attrs.default() { + attr::Default::Default => { + Some(quote!( + let __default: Self::Value = _serde::export::Default::default(); + )) + } + attr::Default::Path(ref path) => { + Some(quote!( + let __default: Self::Value = #path(); + )) + } + attr::Default::None => { + // We don't need the default value, to prevent an unused variable warning + // we'll leave the line empty. + None + } + }; + + quote_block! { + #(#let_values)* + + #match_keys + + #let_default + + #(#extract_values)* + + _serde::export::Ok(#struct_path { #(#result),* }) + } +} + +fn field_i(i: usize) -> Ident { + Ident::new(format!("__field{}", i)) +} + +/// This function wraps the expression in `#[serde(deserialize_with="...")]` in +/// a trait to prevent it from accessing the internal `Deserialize` state. +fn wrap_deserialize_with(ident: &syn::Ident, + generics: &syn::Generics, + field_ty: &syn::Ty, + deserialize_with: &syn::Path) + -> (Tokens, Tokens) { + let (impl_generics, ty_generics, where_clause) = generics.split_for_impl(); + + let wrapper = quote! { + struct __DeserializeWith #impl_generics #where_clause { + value: #field_ty, + phantom: _serde::export::PhantomData<#ident #ty_generics>, + } + + impl #impl_generics _serde::Deserialize for __DeserializeWith #ty_generics #where_clause { + fn deserialize<__D>(__d: __D) -> _serde::export::Result + where __D: _serde::Deserializer + { + let value = try!(#deserialize_with(__d)); + _serde::export::Ok(__DeserializeWith { + value: value, + phantom: _serde::export::PhantomData, + }) + } + } + }; + + let wrapper_ty = quote!(__DeserializeWith #ty_generics); + + (wrapper, wrapper_ty) +} + +fn expr_is_missing(field: &Field, item_attrs: &attr::Item) -> Fragment { + match *field.attrs.default() { + attr::Default::Default => { + return quote_expr!(_serde::export::Default::default()); + } + attr::Default::Path(ref path) => { + return quote_expr!(#path()); + } + attr::Default::None => { /* below */ } + } + + match *item_attrs.default() { + attr::Default::Default | attr::Default::Path(_) => { + let ident = &field.ident; + return quote_expr!(__default.#ident); + } + attr::Default::None => { /* below */ } + } + + let name = field.attrs.name().deserialize_name(); + match field.attrs.deserialize_with() { + None => { + quote_expr! { + try!(_serde::de::private::missing_field(#name)) + } + } + Some(_) => { + quote_expr! { + return _serde::export::Err(<__V::Error as _serde::de::Error>::missing_field(#name)) + } + } + } +} + +fn check_no_str(cx: &internals::Ctxt, item: &Item) { + let fail = || { + cx.error("Serde does not support deserializing fields of type &str; consider using \ + String instead"); + }; + + for field in item.body.all_fields() { + if field.attrs.skip_deserializing() || field.attrs.deserialize_with().is_some() { + continue; + } + + if let syn::Ty::Rptr(_, ref inner) = *field.ty { + if let syn::Ty::Path(_, ref path) = inner.ty { + if path.segments.len() == 1 && path.segments[0].ident == "str" { + fail(); + return; + } + } + } + } +} diff --git a/third_party/rust/serde_derive/src/fragment.rs b/third_party/rust/serde_derive/src/fragment.rs new file mode 100644 index 000000000000..f35578dbd1ad --- /dev/null +++ b/third_party/rust/serde_derive/src/fragment.rs @@ -0,0 +1,67 @@ +use quote::{Tokens, ToTokens}; + +pub enum Fragment { + /// Tokens that can be used as an expression. + Expr(Tokens), + /// Tokens that can be used inside a block. The surrounding curly braces are + /// not part of these tokens. + Block(Tokens), +} + +macro_rules! quote_expr { + ($($tt:tt)*) => { + $crate::fragment::Fragment::Expr(quote!($($tt)*)) + } +} + +macro_rules! quote_block { + ($($tt:tt)*) => { + $crate::fragment::Fragment::Block(quote!($($tt)*)) + } +} + +/// Interpolate a fragment in place of an expression. This involves surrounding +/// Block fragments in curly braces. +pub struct Expr(pub Fragment); +impl ToTokens for Expr { + fn to_tokens(&self, out: &mut Tokens) { + match self.0 { + Fragment::Expr(ref expr) => expr.to_tokens(out), + Fragment::Block(ref block) => { + out.append("{"); + block.to_tokens(out); + out.append("}"); + } + } + } +} + +/// Interpolate a fragment as the statements of a block. +pub struct Stmts(pub Fragment); +impl ToTokens for Stmts { + fn to_tokens(&self, out: &mut Tokens) { + match self.0 { + Fragment::Expr(ref expr) => expr.to_tokens(out), + Fragment::Block(ref block) => block.to_tokens(out), + } + } +} + +/// Interpolate a fragment as the value part of a `match` expression. This +/// involves putting a comma after expressions and curly braces around blocks. +pub struct Match(pub Fragment); +impl ToTokens for Match { + fn to_tokens(&self, out: &mut Tokens) { + match self.0 { + Fragment::Expr(ref expr) => { + expr.to_tokens(out); + out.append(","); + } + Fragment::Block(ref block) => { + out.append("{"); + block.to_tokens(out); + out.append("}"); + } + } + } +} diff --git a/third_party/rust/serde_derive/src/lib.rs b/third_party/rust/serde_derive/src/lib.rs new file mode 100644 index 000000000000..d58271adfb21 --- /dev/null +++ b/third_party/rust/serde_derive/src/lib.rs @@ -0,0 +1,40 @@ +#![cfg_attr(feature = "cargo-clippy", allow(too_many_arguments))] +#![cfg_attr(feature = "cargo-clippy", allow(used_underscore_binding))] + +// The `quote!` macro requires deep recursion. +#![recursion_limit = "192"] + +extern crate syn; +#[macro_use] +extern crate quote; + +extern crate serde_codegen_internals as internals; + +extern crate proc_macro; +use proc_macro::TokenStream; + +#[macro_use] +mod bound; +#[macro_use] +mod fragment; + +mod ser; +mod de; + +#[proc_macro_derive(Serialize, attributes(serde))] +pub fn derive_serialize(input: TokenStream) -> TokenStream { + let input = syn::parse_derive_input(&input.to_string()).unwrap(); + match ser::expand_derive_serialize(&input) { + Ok(expanded) => expanded.parse().unwrap(), + Err(msg) => panic!(msg), + } +} + +#[proc_macro_derive(Deserialize, attributes(serde))] +pub fn derive_deserialize(input: TokenStream) -> TokenStream { + let input = syn::parse_derive_input(&input.to_string()).unwrap(); + match de::expand_derive_deserialize(&input) { + Ok(expanded) => expanded.parse().unwrap(), + Err(msg) => panic!(msg), + } +} diff --git a/third_party/rust/serde_derive/src/ser.rs b/third_party/rust/serde_derive/src/ser.rs new file mode 100644 index 000000000000..425bfa4e9f54 --- /dev/null +++ b/third_party/rust/serde_derive/src/ser.rs @@ -0,0 +1,782 @@ +use syn::{self, Ident}; +use quote::Tokens; + +use bound; +use fragment::{Fragment, Stmts, Match}; +use internals::ast::{Body, Field, Item, Style, Variant}; +use internals::{self, attr}; + +pub fn expand_derive_serialize(item: &syn::DeriveInput) -> Result { + let ctxt = internals::Ctxt::new(); + let item = Item::from_ast(&ctxt, item); + try!(ctxt.check()); + + let ident = &item.ident; + let generics = build_generics(&item); + let (impl_generics, ty_generics, where_clause) = generics.split_for_impl(); + let dummy_const = Ident::new(format!("_IMPL_SERIALIZE_FOR_{}", ident)); + let body = Stmts(serialize_body(&item, &generics)); + + Ok(quote! { + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + const #dummy_const: () = { + extern crate serde as _serde; + #[automatically_derived] + impl #impl_generics _serde::Serialize for #ident #ty_generics #where_clause { + fn serialize<__S>(&self, _serializer: __S) -> _serde::export::Result<__S::Ok, __S::Error> + where __S: _serde::Serializer + { + #body + } + } + }; + }) +} + +// All the generics in the input, plus a bound `T: Serialize` for each generic +// field type that will be serialized by us. +fn build_generics(item: &Item) -> syn::Generics { + let generics = bound::without_defaults(item.generics); + + let generics = + bound::with_where_predicates_from_fields(item, &generics, attr::Field::ser_bound); + + match item.attrs.ser_bound() { + Some(predicates) => bound::with_where_predicates(&generics, predicates), + None => { + bound::with_bound(item, + &generics, + needs_serialize_bound, + &path!(_serde::Serialize)) + } + } +} + +// Fields with a `skip_serializing` or `serialize_with` attribute are not +// serialized by us so we do not generate a bound. Fields with a `bound` +// attribute specify their own bound so we do not generate one. All other fields +// may need a `T: Serialize` bound where T is the type of the field. +fn needs_serialize_bound(attrs: &attr::Field) -> bool { + !attrs.skip_serializing() && attrs.serialize_with().is_none() && attrs.ser_bound().is_none() +} + +fn serialize_body(item: &Item, generics: &syn::Generics) -> Fragment { + match item.body { + Body::Enum(ref variants) => { + serialize_item_enum(&item.ident, generics, variants, &item.attrs) + } + Body::Struct(Style::Struct, ref fields) => { + if fields.iter().any(|field| field.ident.is_none()) { + panic!("struct has unnamed fields"); + } + + serialize_struct(&item.ident, generics, fields, &item.attrs) + } + Body::Struct(Style::Tuple, ref fields) => { + if fields.iter().any(|field| field.ident.is_some()) { + panic!("tuple struct has named fields"); + } + + serialize_tuple_struct(&item.ident, generics, fields, &item.attrs) + } + Body::Struct(Style::Newtype, ref fields) => { + serialize_newtype_struct(&item.ident, generics, &fields[0], &item.attrs) + } + Body::Struct(Style::Unit, _) => serialize_unit_struct(&item.attrs), + } +} + +fn serialize_unit_struct(item_attrs: &attr::Item) -> Fragment { + let type_name = item_attrs.name().serialize_name(); + + quote_expr! { + _serde::Serializer::serialize_unit_struct(_serializer, #type_name) + } +} + +fn serialize_newtype_struct(ident: &syn::Ident, + generics: &syn::Generics, + field: &Field, + item_attrs: &attr::Item) + -> Fragment { + let type_name = item_attrs.name().serialize_name(); + + let mut field_expr = quote!(&self.0); + if let Some(path) = field.attrs.serialize_with() { + field_expr = wrap_serialize_with(ident, generics, field.ty, path, field_expr); + } + + quote_expr! { + _serde::Serializer::serialize_newtype_struct(_serializer, #type_name, #field_expr) + } +} + +fn serialize_tuple_struct(ident: &syn::Ident, + generics: &syn::Generics, + fields: &[Field], + item_attrs: &attr::Item) + -> Fragment { + let serialize_stmts = + serialize_tuple_struct_visitor(ident, + fields, + generics, + false, + quote!(_serde::ser::SerializeTupleStruct::serialize_field)); + + let type_name = item_attrs.name().serialize_name(); + let len = serialize_stmts.len(); + let let_mut = mut_if(len > 0); + + quote_block! { + let #let_mut __serde_state = try!(_serde::Serializer::serialize_tuple_struct(_serializer, #type_name, #len)); + #(#serialize_stmts)* + _serde::ser::SerializeTupleStruct::end(__serde_state) + } +} + +fn serialize_struct(ident: &syn::Ident, + generics: &syn::Generics, + fields: &[Field], + item_attrs: &attr::Item) + -> Fragment { + let serialize_fields = + serialize_struct_visitor(ident, + fields, + generics, + false, + quote!(_serde::ser::SerializeStruct::serialize_field)); + + let type_name = item_attrs.name().serialize_name(); + + let mut serialized_fields = fields.iter() + .filter(|&field| !field.attrs.skip_serializing()) + .peekable(); + + let let_mut = mut_if(serialized_fields.peek().is_some()); + + let len = serialized_fields.map(|field| { + let ident = field.ident.clone().expect("struct has unnamed fields"); + let field_expr = quote!(&self.#ident); + + match field.attrs.skip_serializing_if() { + Some(path) => quote!(if #path(#field_expr) { 0 } else { 1 }), + None => quote!(1), + } + }) + .fold(quote!(0), |sum, expr| quote!(#sum + #expr)); + + quote_block! { + let #let_mut __serde_state = try!(_serde::Serializer::serialize_struct(_serializer, #type_name, #len)); + #(#serialize_fields)* + _serde::ser::SerializeStruct::end(__serde_state) + } +} + +fn serialize_item_enum(ident: &syn::Ident, + generics: &syn::Generics, + variants: &[Variant], + item_attrs: &attr::Item) + -> Fragment { + let arms: Vec<_> = variants.iter() + .enumerate() + .map(|(variant_index, variant)| { + serialize_variant(ident, + generics, + variant, + variant_index, + item_attrs) + }) + .collect(); + + quote_expr! { + match *self { + #(#arms)* + } + } +} + +fn serialize_variant(ident: &syn::Ident, + generics: &syn::Generics, + variant: &Variant, + variant_index: usize, + item_attrs: &attr::Item) + -> Tokens { + let variant_ident = variant.ident.clone(); + + if variant.attrs.skip_serializing() { + let skipped_msg = format!("the enum variant {}::{} cannot be serialized", + ident, variant_ident); + let skipped_err = quote! { + _serde::export::Err(_serde::ser::Error::custom(#skipped_msg)) + }; + let fields_pat = match variant.style { + Style::Unit => quote!(), + Style::Newtype | Style::Tuple => quote!( (..) ), + Style::Struct => quote!( {..} ), + }; + quote! { + #ident::#variant_ident #fields_pat => #skipped_err, + } + } else { + // variant wasn't skipped + let case = match variant.style { + Style::Unit => { + quote! { + #ident::#variant_ident + } + } + Style::Newtype => { + quote! { + #ident::#variant_ident(ref __field0) + } + } + Style::Tuple => { + let field_names = (0..variant.fields.len()) + .map(|i| Ident::new(format!("__field{}", i))); + quote! { + #ident::#variant_ident(#(ref #field_names),*) + } + } + Style::Struct => { + let fields = variant.fields + .iter() + .map(|f| f.ident.clone().expect("struct variant has unnamed fields")); + quote! { + #ident::#variant_ident { #(ref #fields),* } + } + } + }; + + let body = Match(match *item_attrs.tag() { + attr::EnumTag::External => { + serialize_externally_tagged_variant(ident, + generics, + variant, + variant_index, + item_attrs) + } + attr::EnumTag::Internal { ref tag } => { + serialize_internally_tagged_variant(ident, + generics, + variant, + item_attrs, + tag) + } + attr::EnumTag::Adjacent { ref tag, ref content } => { + serialize_adjacently_tagged_variant(ident, + generics, + variant, + item_attrs, + tag, + content) + } + attr::EnumTag::None => serialize_untagged_variant(ident, generics, variant, item_attrs), + }); + + quote! { + #case => #body + } + } +} + +fn serialize_externally_tagged_variant(ident: &syn::Ident, + generics: &syn::Generics, + variant: &Variant, + variant_index: usize, + item_attrs: &attr::Item) + -> Fragment { + let type_name = item_attrs.name().serialize_name(); + let variant_name = variant.attrs.name().serialize_name(); + + match variant.style { + Style::Unit => { + quote_expr! { + _serde::Serializer::serialize_unit_variant( + _serializer, + #type_name, + #variant_index, + #variant_name, + ) + } + } + Style::Newtype => { + let field = &variant.fields[0]; + let mut field_expr = quote!(__field0); + if let Some(path) = field.attrs.serialize_with() { + field_expr = wrap_serialize_with(ident, generics, field.ty, path, field_expr); + } + + quote_expr! { + _serde::Serializer::serialize_newtype_variant( + _serializer, + #type_name, + #variant_index, + #variant_name, + #field_expr, + ) + } + } + Style::Tuple => { + serialize_tuple_variant(TupleVariant::ExternallyTagged { + type_name: type_name, + variant_index: variant_index, + variant_name: variant_name, + }, + ident, + generics, + &variant.fields) + } + Style::Struct => { + serialize_struct_variant(StructVariant::ExternallyTagged { + variant_index: variant_index, + variant_name: variant_name, + }, + ident, + generics, + &variant.fields, + &type_name) + } + } +} + +fn serialize_internally_tagged_variant(ident: &syn::Ident, + generics: &syn::Generics, + variant: &Variant, + item_attrs: &attr::Item, + tag: &str) + -> Fragment { + let type_name = item_attrs.name().serialize_name(); + let variant_name = variant.attrs.name().serialize_name(); + + let enum_ident_str = ident.as_ref(); + let variant_ident_str = variant.ident.as_ref(); + + match variant.style { + Style::Unit => { + quote_block! { + let mut __struct = try!(_serde::Serializer::serialize_struct( + _serializer, #type_name, 1)); + try!(_serde::ser::SerializeStruct::serialize_field( + &mut __struct, #tag, #variant_name)); + _serde::ser::SerializeStruct::end(__struct) + } + } + Style::Newtype => { + let field = &variant.fields[0]; + let mut field_expr = quote!(__field0); + if let Some(path) = field.attrs.serialize_with() { + field_expr = wrap_serialize_with(ident, generics, field.ty, path, field_expr); + } + + quote_expr! { + _serde::ser::private::serialize_tagged_newtype( + _serializer, + #enum_ident_str, + #variant_ident_str, + #tag, + #variant_name, + #field_expr, + ) + } + } + Style::Struct => { + serialize_struct_variant(StructVariant::InternallyTagged { + tag: tag, + variant_name: variant_name, + }, + ident, + generics, + &variant.fields, + &type_name) + } + Style::Tuple => unreachable!("checked in serde_codegen_internals"), + } +} + +fn serialize_adjacently_tagged_variant(ident: &syn::Ident, + generics: &syn::Generics, + variant: &Variant, + item_attrs: &attr::Item, + tag: &str, + content: &str) + -> Fragment { + let type_name = item_attrs.name().serialize_name(); + let variant_name = variant.attrs.name().serialize_name(); + + let inner = Stmts(match variant.style { + Style::Unit => { + return quote_block! { + let mut __struct = try!(_serde::Serializer::serialize_struct( + _serializer, #type_name, 1)); + try!(_serde::ser::SerializeStruct::serialize_field( + &mut __struct, #tag, #variant_name)); + _serde::ser::SerializeStruct::end(__struct) + }; + } + Style::Newtype => { + let field = &variant.fields[0]; + let mut field_expr = quote!(__field0); + if let Some(path) = field.attrs.serialize_with() { + field_expr = wrap_serialize_with(ident, generics, field.ty, path, field_expr); + } + + quote_expr! { + _serde::Serialize::serialize(#field_expr, _serializer) + } + } + Style::Tuple => { + serialize_tuple_variant(TupleVariant::Untagged, + ident, + generics, + &variant.fields) + } + Style::Struct => { + serialize_struct_variant(StructVariant::Untagged, + ident, + generics, + &variant.fields, + &variant_name) + } + }); + + let fields_ty = variant.fields.iter().map(|f| &f.ty); + let ref fields_ident: Vec<_> = match variant.style { + Style::Unit => unreachable!(), + Style::Newtype => vec![Ident::new("__field0")], + Style::Tuple => { + (0..variant.fields.len()) + .map(|i| Ident::new(format!("__field{}", i))) + .collect() + } + Style::Struct => { + variant.fields + .iter() + .map(|f| f.ident.clone().expect("struct variant has unnamed fields")) + .collect() + } + }; + + let (_, ty_generics, where_clause) = generics.split_for_impl(); + + let wrapper_generics = bound::with_lifetime_bound(generics, "'__a"); + let (wrapper_impl_generics, wrapper_ty_generics, _) = wrapper_generics.split_for_impl(); + + quote_block! { + struct __AdjacentlyTagged #wrapper_generics #where_clause { + data: (#(&'__a #fields_ty,)*), + phantom: _serde::export::PhantomData<#ident #ty_generics>, + } + + impl #wrapper_impl_generics _serde::Serialize for __AdjacentlyTagged #wrapper_ty_generics #where_clause { + fn serialize<__S>(&self, _serializer: __S) -> _serde::export::Result<__S::Ok, __S::Error> + where __S: _serde::Serializer + { + let (#(#fields_ident,)*) = self.data; + #inner + } + } + + let mut __struct = try!(_serde::Serializer::serialize_struct( + _serializer, #type_name, 2)); + try!(_serde::ser::SerializeStruct::serialize_field( + &mut __struct, #tag, #variant_name)); + try!(_serde::ser::SerializeStruct::serialize_field( + &mut __struct, #content, &__AdjacentlyTagged { + data: (#(#fields_ident,)*), + phantom: _serde::export::PhantomData::<#ident #ty_generics>, + })); + _serde::ser::SerializeStruct::end(__struct) + } +} + +fn serialize_untagged_variant(ident: &syn::Ident, + generics: &syn::Generics, + variant: &Variant, + item_attrs: &attr::Item) + -> Fragment { + match variant.style { + Style::Unit => { + quote_expr! { + _serde::Serializer::serialize_unit(_serializer) + } + } + Style::Newtype => { + let field = &variant.fields[0]; + let mut field_expr = quote!(__field0); + if let Some(path) = field.attrs.serialize_with() { + field_expr = wrap_serialize_with(ident, generics, field.ty, path, field_expr); + } + + quote_expr! { + _serde::Serialize::serialize(#field_expr, _serializer) + } + } + Style::Tuple => { + serialize_tuple_variant(TupleVariant::Untagged, ident, generics, &variant.fields) + } + Style::Struct => { + let type_name = item_attrs.name().serialize_name(); + serialize_struct_variant(StructVariant::Untagged, + ident, + generics, + &variant.fields, + &type_name) + } + } +} + +enum TupleVariant { + ExternallyTagged { + type_name: String, + variant_index: usize, + variant_name: String, + }, + Untagged, +} + +fn serialize_tuple_variant(context: TupleVariant, + ident: &syn::Ident, + generics: &syn::Generics, + fields: &[Field]) + -> Fragment { + let method = match context { + TupleVariant::ExternallyTagged { .. } => { + quote!(_serde::ser::SerializeTupleVariant::serialize_field) + } + TupleVariant::Untagged => quote!(_serde::ser::SerializeTuple::serialize_element), + }; + + let serialize_stmts = + serialize_tuple_struct_visitor(ident, fields, generics, true, method); + + let len = serialize_stmts.len(); + let let_mut = mut_if(len > 0); + + match context { + TupleVariant::ExternallyTagged { type_name, variant_index, variant_name } => { + quote_block! { + let #let_mut __serde_state = try!(_serde::Serializer::serialize_tuple_variant( + _serializer, + #type_name, + #variant_index, + #variant_name, + #len)); + #(#serialize_stmts)* + _serde::ser::SerializeTupleVariant::end(__serde_state) + } + } + TupleVariant::Untagged => { + quote_block! { + let #let_mut __serde_state = try!(_serde::Serializer::serialize_tuple( + _serializer, + #len)); + #(#serialize_stmts)* + _serde::ser::SerializeTuple::end(__serde_state) + } + } + } +} + +enum StructVariant<'a> { + ExternallyTagged { + variant_index: usize, + variant_name: String, + }, + InternallyTagged { tag: &'a str, variant_name: String }, + Untagged, +} + +fn serialize_struct_variant<'a>(context: StructVariant<'a>, + ident: &syn::Ident, + generics: &syn::Generics, + fields: &[Field], + name: &str) + -> Fragment { + let method = match context { + StructVariant::ExternallyTagged { .. } => { + quote!(_serde::ser::SerializeStructVariant::serialize_field) + } + StructVariant::InternallyTagged { .. } | + StructVariant::Untagged => quote!(_serde::ser::SerializeStruct::serialize_field), + }; + + let serialize_fields = serialize_struct_visitor(ident, fields, generics, true, method); + + let mut serialized_fields = fields.iter() + .filter(|&field| !field.attrs.skip_serializing()) + .peekable(); + + let let_mut = mut_if(serialized_fields.peek().is_some()); + + let len = serialized_fields.map(|field| { + let ident = field.ident.clone().expect("struct has unnamed fields"); + + match field.attrs.skip_serializing_if() { + Some(path) => quote!(if #path(#ident) { 0 } else { 1 }), + None => quote!(1), + } + }) + .fold(quote!(0), |sum, expr| quote!(#sum + #expr)); + + match context { + StructVariant::ExternallyTagged { variant_index, variant_name } => { + quote_block! { + let #let_mut __serde_state = try!(_serde::Serializer::serialize_struct_variant( + _serializer, + #name, + #variant_index, + #variant_name, + #len, + )); + #(#serialize_fields)* + _serde::ser::SerializeStructVariant::end(__serde_state) + } + } + StructVariant::InternallyTagged { tag, variant_name } => { + quote_block! { + let mut __serde_state = try!(_serde::Serializer::serialize_struct( + _serializer, + #name, + #len + 1, + )); + try!(_serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + #tag, + #variant_name, + )); + #(#serialize_fields)* + _serde::ser::SerializeStruct::end(__serde_state) + } + } + StructVariant::Untagged => { + quote_block! { + let #let_mut __serde_state = try!(_serde::Serializer::serialize_struct( + _serializer, + #name, + #len, + )); + #(#serialize_fields)* + _serde::ser::SerializeStruct::end(__serde_state) + } + } + } +} + +fn serialize_tuple_struct_visitor(ident: &syn::Ident, + fields: &[Field], + generics: &syn::Generics, + is_enum: bool, + func: Tokens) + -> Vec { + fields.iter() + .enumerate() + .map(|(i, field)| { + let mut field_expr = if is_enum { + let id = Ident::new(format!("__field{}", i)); + quote!(#id) + } else { + let i = Ident::new(i); + quote!(&self.#i) + }; + + let skip = field.attrs + .skip_serializing_if() + .map(|path| quote!(#path(#field_expr))); + + if let Some(path) = field.attrs.serialize_with() { + field_expr = + wrap_serialize_with(ident, generics, field.ty, path, field_expr); + } + + let ser = quote! { + try!(#func(&mut __serde_state, #field_expr)); + }; + + match skip { + None => ser, + Some(skip) => quote!(if !#skip { #ser }), + } + }) + .collect() +} + +fn serialize_struct_visitor(ident: &syn::Ident, + fields: &[Field], + generics: &syn::Generics, + is_enum: bool, + func: Tokens) + -> Vec { + fields.iter() + .filter(|&field| !field.attrs.skip_serializing()) + .map(|field| { + let field_ident = field.ident.clone().expect("struct has unnamed field"); + let mut field_expr = if is_enum { + quote!(#field_ident) + } else { + quote!(&self.#field_ident) + }; + + let key_expr = field.attrs.name().serialize_name(); + + let skip = field.attrs + .skip_serializing_if() + .map(|path| quote!(#path(#field_expr))); + + if let Some(path) = field.attrs.serialize_with() { + field_expr = + wrap_serialize_with(ident, generics, field.ty, path, field_expr) + } + + let ser = quote! { + try!(#func(&mut __serde_state, #key_expr, #field_expr)); + }; + + match skip { + None => ser, + Some(skip) => quote!(if !#skip { #ser }), + } + }) + .collect() +} + +fn wrap_serialize_with(ident: &syn::Ident, + generics: &syn::Generics, + field_ty: &syn::Ty, + serialize_with: &syn::Path, + value: Tokens) + -> Tokens { + let (_, ty_generics, where_clause) = generics.split_for_impl(); + + let wrapper_generics = bound::with_lifetime_bound(generics, "'__a"); + let (wrapper_impl_generics, wrapper_ty_generics, _) = wrapper_generics.split_for_impl(); + + quote!({ + struct __SerializeWith #wrapper_impl_generics #where_clause { + value: &'__a #field_ty, + phantom: _serde::export::PhantomData<#ident #ty_generics>, + } + + impl #wrapper_impl_generics _serde::Serialize for __SerializeWith #wrapper_ty_generics #where_clause { + fn serialize<__S>(&self, __s: __S) -> _serde::export::Result<__S::Ok, __S::Error> + where __S: _serde::Serializer + { + #serialize_with(self.value, __s) + } + } + + &__SerializeWith { + value: #value, + phantom: _serde::export::PhantomData::<#ident #ty_generics>, + } + }) +} + +// Serialization of an empty struct results in code like: +// +// let mut __serde_state = try!(serializer.serialize_struct("S", 0)); +// _serde::ser::SerializeStruct::end(__serde_state) +// +// where we want to omit the `mut` to avoid a warning. +fn mut_if(is_mut: bool) -> Option { + if is_mut { Some(quote!(mut)) } else { None } +} diff --git a/third_party/rust/servo-dwrote/.cargo-checksum.json b/third_party/rust/servo-dwrote/.cargo-checksum.json deleted file mode 100644 index fd594ab7f0f4..000000000000 --- a/third_party/rust/servo-dwrote/.cargo-checksum.json +++ /dev/null @@ -1 +0,0 @@ -{"files":{".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",".gitignore":"172610b244a5ee8a8e2f1f045058b8abf9291d84bb76bf8779d2fd420419c2d6","Cargo.toml":"dea6c3d3d4b1440983aa6e3d218b52c630283c8ef52102fa5443c67d954e14f0","README.md":"d69d75705e2582721cbfb2d3b4b2af052c71679057a0b2ac53a22c03f1755bba","build.rs":"b40ce243f62825724b4a45092a8e658d71fa952a6840b83f3bee58e719a56d3b","src/bitmap_render_target.rs":"d3b229f85a9804ac52976431657727b410e7d5253283df046e46d98c196f0a3a","src/com_helpers.rs":"fccb4b36379ae3454a88aa32a8e5c09e46ef5f5626266dde1fe5f40a992de39c","src/comptr.rs":"218435689f505769686e07cfc5428852dda90b849a0d48e670f632307f5edc7c","src/font.rs":"9bdf3134c6ad3639eab3da4419c9b43aad2673797f6fdc65841da2c82e1f3af4","src/font_collection.rs":"969fa3abf141dc3504774886f4783fda4a74cd5a198c643f8a77fc1af4e75258","src/font_face.rs":"9506ca579345ab2b6b5615fc75f8f431e2bb0dbd93123d1d2a21a73c851a5427","src/font_family.rs":"403da9f8f9903cbe7f9f79636497b273f9885e200f53af99f9d4e483f11d6889","src/font_file.rs":"60ad02fc25765a2c113175ea372e98a2be0d84aa65fef9246b6a0192e63ff708","src/font_file_loader_impl.rs":"0d304ad99ff1e6874510a1498223329d798ff75b417e3db7e823a695003dfe92","src/gdi_interop.rs":"98922996afc5b8c8304cb65e7c965419003825dfa172a3e11fe69bf3d768551c","src/glyph_run_analysis.rs":"d30d8b41b047815ab5770c730b7a6d09939f2347b4a4257b87bebec08a5794fe","src/helpers.rs":"5d6f164468234ca8806dc1cea117b42dbfae80cc4c9ae965cb0556efdb364682","src/lib.rs":"7dc9d6bbe0ca46082b5c7d049b230388ff2681831506b2798d7ab6e478e18693","src/rendering_params.rs":"be1d1c433f76926c285d8ecdb747c5d9cc6a6c10c1a1890c0760cd99755ed471","src/test.rs":"d77e45f8866abeea070cbbafd4cbde62d875292e8d191310a04c70091978547c","src/types.rs":"784235c15d61fb0d001373575169aa473c92af18dcbc1709a5b2bbaa3a7ceb22"},"package":"9f013da79c3fb2a9653534b064cd2ca62e10f8b6d19ed8fdc885cb2873412789"} \ No newline at end of file diff --git a/third_party/rust/servo-dwrote/Cargo.toml b/third_party/rust/servo-dwrote/Cargo.toml deleted file mode 100644 index c7aec0c6db3a..000000000000 --- a/third_party/rust/servo-dwrote/Cargo.toml +++ /dev/null @@ -1,30 +0,0 @@ -[package] -name = "servo-dwrote" -description = "Lightweight binding to DirectWrite." -repository = "https://github.com/servo/dwrote-rs" -license = "MPL-2.0" -version = "0.2.0" -authors = ["Vladimir Vukicevic "] -build = "build.rs" - -[lib] -name = "dwrote" - -[features] -default = ["codegen"] -nightly = ["serde/unstable"] -codegen = ["serde_codegen", "serde_codegen/with-syntex"] - -[dependencies] -libc = "0.2" -lazy_static = "0.2" -winapi = "0.2" -kernel32-sys = "0.2" -gdi32-sys = "0.2" -serde = "0.9" -serde_derive = {version = "0.9", optional = true} - -[build-dependencies.serde_codegen] -version = "0.9" -default_features = false -optional = true diff --git a/third_party/rust/servo-dwrote/build.rs b/third_party/rust/servo-dwrote/build.rs deleted file mode 100644 index c07d8d8a6eba..000000000000 --- a/third_party/rust/servo-dwrote/build.rs +++ /dev/null @@ -1,46 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#[cfg(all(feature = "serde_codegen", not(feature = "serde_derive")))] -mod inner { - extern crate serde_codegen; - - use std::env; - use std::path::Path; - - pub fn main() { - let out_dir = env::var_os("OUT_DIR").unwrap(); - - let src = Path::new("src/types.rs"); - let dst = Path::new(&out_dir).join("types.rs"); - - serde_codegen::expand(&src, &dst).unwrap(); - println!("cargo:rerun-if-changed=src/types.rs"); - } -} - -#[cfg(all(feature = "serde_derive", not(feature = "serde_codegen")))] -mod inner { - pub fn main() {} -} - -#[cfg(all(feature = "serde_codegen", feature = "serde_derive"))] -mod inner { - pub fn main() { - panic!("serde_codegen and serde_derive are both used. \ - You probably forgot --no-default-features.") - } -} - -#[cfg(not(any(feature = "serde_codegen", feature = "serde_derive")))] -mod inner { - pub fn main() { - panic!("Neither serde_codegen nor serde_derive are used. " - "You probably want --features serde_derive --no-default-features.") - } -} - -fn main() { - inner::main(); -} diff --git a/third_party/rust/syn-0.10.8/.cargo-checksum.json b/third_party/rust/syn-0.10.8/.cargo-checksum.json deleted file mode 100644 index f0ed90a87b2d..000000000000 --- a/third_party/rust/syn-0.10.8/.cargo-checksum.json +++ /dev/null @@ -1 +0,0 @@ -{"files":{".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","Cargo.toml":"f703ce140afaec1a35ce733f6bc3d0ce45a6256095572d0763c815fbf39f4f11","src/aster/generics.rs":"77eb19443af0dff5debb18d064733cc8721a42ad7e993a33352cdeff2b5f9f85","src/aster/ident.rs":"e9d082664f008a56bd854011310b4258ab072740ba82e57495b6e8a868a5f36b","src/aster/invoke.rs":"2b1b993973ab4f5c8fa6d6a286576b2542edce21fe9904f5133c470c072e6d3f","src/aster/lifetime.rs":"d83f4c1a48e3580caa028cfabde6ace232efc95d70af6dc9cfcca48317db9ad7","src/aster/mod.rs":"12220f73b0021e72b4c50f6a513cff174b9c7267209aa23f183043d96ccc9ab7","src/aster/path.rs":"60865b0f952077307c1a66810a4b6dafde43e76a417a433a8343960e7de474e4","src/aster/qpath.rs":"885c94b29ab8ee45c72a682221e241d1f0dd09c659809fe77279b5dd8a4bc645","src/aster/ty.rs":"90649aad98617c09ffc43a38aeb823a3298c41bf5e10f0ef3500b71c81021c2f","src/aster/ty_param.rs":"7ced1e6ca0c98ef468d507d3f07bfcb1171395cd66ff5c3e1b091fe7e8b9a562","src/aster/where_predicate.rs":"5fb8ec3fcb67bcc1d9bb7b64cf2f5beb601aac6502d6db30c0cdf8641fa248d1","src/attr.rs":"2ba436bdd439511be10baf9ad45226ade678176a7fd45a087367e1ad2b43e07a","src/constant.rs":"90535a2320e0dc8ab623a9bffa770bdf697baef2884a7d9224b31daf422ea5a0","src/data.rs":"0119c67821f846e67d792bea638ae7f7f5d7e2f5e5a0c145d8ba8766d6ddb0f9","src/escape.rs":"e035b1f6ce3255e868fddb62ee90a95a2f3caf2db73786a2b179b92e9e337539","src/expr.rs":"02e8d346bef099974d06d74945be92fe6391111b94154df4981d44f1594d5579","src/generics.rs":"a300acff4c6e61d2fe9344db23f5e176e7abb02529bc348d9180f41ad0a4caf6","src/helper.rs":"9693d5c78f2d627a90d689a5d4bee1061eddcb646ae6dff3b2e4fd7cfbb33845","src/ident.rs":"83142b0107baba3137aad3b7d5c7b468ab53bf837bd9544d117d6644080d2705","src/item.rs":"63f2cd9a01c279405196d90a7d1cc530896157352163fb44f6b2a713657058b8","src/krate.rs":"324073a42389eb1c26a9d0f325b4f1cdd37d00a9bcaf07fdee77af54909a452d","src/lib.rs":"ef584db9ac9b7308224798d3983cbf201df7f0da1735fe5ce408f20fb3df763e","src/lit.rs":"2615fc6041f11b67a7cd62012f36eb215fd1fdf6649b6b64d728625148f53c7b","src/mac.rs":"45c44bd7abcbdaea6572bb4721bdc57b02b967ea9865172fe10e029e51e51a42","src/macro_input.rs":"93b999877879076e1f47502d96aa18aad82117d072044ca9de825c8a9bfa60b8","src/nom.rs":"642149bf322b762e02183ac1fed641df7f03ac53334c869a64707de4e9c5e68c","src/op.rs":"232f84ba605ed50e70ee02169dd551548872135cf56f155637917ec3bf810ce1","src/registry.rs":"b709f2a0f372efd8dec8fd46d6d71fb3b56a0261789e6de048a41a5e70144421","src/space.rs":"de9cb71e831c1d66f0bf2f3f219c3455d1979ca89f89b198d3b324e0cd50faf8","src/ty.rs":"97cfcb904a5fd68a42ebd2e5f86466d92e0785b1491d80c2a8d396ccec1b742a","src/visit.rs":"d7dcf429cc1a05821a66a4b38e7856eec45a9b2215f625d95030c3688eda26ca"},"package":"58fd09df59565db3399efbba34ba8a2fec1307511ebd245d0061ff9d42691673"} \ No newline at end of file diff --git a/third_party/rust/syn-0.10.8/.cargo-ok b/third_party/rust/syn-0.10.8/.cargo-ok deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/third_party/rust/syn-0.10.8/Cargo.toml b/third_party/rust/syn-0.10.8/Cargo.toml deleted file mode 100644 index 13b273d943eb..000000000000 --- a/third_party/rust/syn-0.10.8/Cargo.toml +++ /dev/null @@ -1,32 +0,0 @@ -[package] -name = "syn" -version = "0.10.8" # don't forget to update version in readme for breaking changes -authors = ["David Tolnay "] -license = "MIT/Apache-2.0" -description = "Nom parser for Rust source code" -repository = "https://github.com/dtolnay/syn" -documentation = "https://dtolnay.github.io/syn/syn/" -include = ["Cargo.toml", "src/**/*.rs"] - -[features] -default = ["parsing", "printing"] -aster = [] -expand = ["full", "parsing", "printing"] -full = [] -parsing = ["unicode-xid"] -pretty = ["syntex_syntax"] -printing = ["quote"] -visit = [] - -[dependencies] -clippy = { version = "0.*", optional = true } -quote = { version = "0.3.0", optional = true } -syntex_syntax = { version = "0.50.0", optional = true } -unicode-xid = { version = "0.0.4", optional = true } - -[dev-dependencies] -syntex_pos = "0.50.0" -syntex_syntax = "0.50.0" -tempdir = "0.3.5" -time = "0.1.35" -walkdir = "1.0.1" diff --git a/third_party/rust/syn-0.10.8/src/aster/generics.rs b/third_party/rust/syn-0.10.8/src/aster/generics.rs deleted file mode 100644 index 8feb87cf013f..000000000000 --- a/third_party/rust/syn-0.10.8/src/aster/generics.rs +++ /dev/null @@ -1,233 +0,0 @@ -use {Generics, Ident, LifetimeDef, TyParam, WhereClause, WherePredicate}; -use aster::invoke::{Identity, Invoke}; -use aster::lifetime::{IntoLifetime, LifetimeDefBuilder, IntoLifetimeDef}; -use aster::path::IntoPath; -use aster::ty_param::TyParamBuilder; -use aster::where_predicate::WherePredicateBuilder; - -pub struct GenericsBuilder { - callback: F, - lifetimes: Vec, - ty_params: Vec, - predicates: Vec, -} - -impl GenericsBuilder { - pub fn new() -> Self { - GenericsBuilder::with_callback(Identity) - } - - pub fn from_generics(generics: Generics) -> Self { - GenericsBuilder::from_generics_with_callback(generics, Identity) - } -} - -impl GenericsBuilder - where F: Invoke -{ - pub fn with_callback(callback: F) -> Self { - GenericsBuilder { - callback: callback, - lifetimes: Vec::new(), - ty_params: Vec::new(), - predicates: Vec::new(), - } - } - - pub fn from_generics_with_callback(generics: Generics, callback: F) -> Self { - GenericsBuilder { - callback: callback, - lifetimes: generics.lifetimes, - ty_params: generics.ty_params, - predicates: generics.where_clause.predicates, - } - } - - pub fn with(self, generics: Generics) -> Self { - self.with_lifetimes(generics.lifetimes.into_iter()) - .with_ty_params(generics.ty_params.into_iter()) - .with_predicates(generics.where_clause.predicates.into_iter()) - } - - pub fn with_lifetimes(mut self, iter: I) -> Self - where I: IntoIterator, - L: IntoLifetimeDef - { - let iter = iter.into_iter().map(|lifetime_def| lifetime_def.into_lifetime_def()); - self.lifetimes.extend(iter); - self - } - - pub fn with_lifetime_names(mut self, iter: I) -> Self - where I: IntoIterator, - N: Into - { - for name in iter { - self = self.lifetime_name(name); - } - self - } - - pub fn with_lifetime(mut self, lifetime: LifetimeDef) -> Self { - self.lifetimes.push(lifetime); - self - } - - pub fn lifetime_name(self, name: N) -> Self - where N: Into - { - self.lifetime(name).build() - } - - pub fn lifetime(self, name: N) -> LifetimeDefBuilder - where N: Into - { - LifetimeDefBuilder::with_callback(name, self) - } - - pub fn with_ty_params(mut self, iter: I) -> Self - where I: IntoIterator - { - self.ty_params.extend(iter); - self - } - - pub fn with_ty_param_ids(mut self, iter: I) -> Self - where I: IntoIterator, - T: Into - { - for id in iter { - self = self.ty_param_id(id); - } - self - } - - pub fn with_ty_param(mut self, ty_param: TyParam) -> Self { - self.ty_params.push(ty_param); - self - } - - pub fn ty_param_id(self, id: I) -> Self - where I: Into - { - self.ty_param(id).build() - } - - pub fn ty_param(self, id: I) -> TyParamBuilder - where I: Into - { - TyParamBuilder::with_callback(id, self) - } - - pub fn with_predicates(mut self, iter: I) -> Self - where I: IntoIterator - { - self.predicates.extend(iter); - self - } - - pub fn with_predicate(mut self, predicate: WherePredicate) -> Self { - self.predicates.push(predicate); - self - } - - pub fn predicate(self) -> WherePredicateBuilder { - WherePredicateBuilder::with_callback(self) - } - - pub fn add_lifetime_bound(mut self, lifetime: L) -> Self - where L: IntoLifetime - { - let lifetime = lifetime.into_lifetime(); - - for lifetime_def in &mut self.lifetimes { - lifetime_def.bounds.push(lifetime.clone()); - } - - for ty_param in &mut self.ty_params { - *ty_param = TyParamBuilder::from_ty_param(ty_param.clone()) - .lifetime_bound(lifetime.clone()) - .build(); - } - - self - } - - pub fn add_ty_param_bound

(self, path: P) -> PolyTraitRefBuilder - where P: IntoPath - { - PolyTraitRefBuilder::with_callback(path, self) - } - - pub fn lifetime_bound(mut self, lifetime: L) -> Self - where L: IntoLifetime - { - let lifetime = lifetime.into_lifetime(); - - self.bounds.push(TyParamBound::Region(lifetime)); - self - } - - pub fn build(self) -> F::Result { - self.callback.invoke(TyParam { - attrs: vec![], - ident: self.id, - bounds: self.bounds, - default: self.default, - }) - } -} - -impl Invoke for TyParamBuilder - where F: Invoke -{ - type Result = Self; - - fn invoke(self, ty: Ty) -> Self { - self.with_default(ty) - } -} - -impl Invoke for TyParamBuilder - where F: Invoke -{ - type Result = Self; - - fn invoke(self, bound: TyParamBound) -> Self { - self.with_bound(bound) - } -} - -impl Invoke for TyParamBuilder - where F: Invoke -{ - type Result = Self; - - fn invoke(self, trait_ref: PolyTraitRef) -> Self { - self.with_trait_bound(trait_ref) - } -} - -// //////////////////////////////////////////////////////////////////////////// - -pub struct TyParamBoundBuilder { - callback: F, -} - -impl TyParamBoundBuilder { - pub fn new() -> Self { - TyParamBoundBuilder::with_callback(Identity) - } -} - -impl TyParamBoundBuilder - where F: Invoke -{ - pub fn with_callback(callback: F) -> Self { - TyParamBoundBuilder { callback: callback } - } - - pub fn build_trait(self, poly_trait: PolyTraitRef, modifier: TraitBoundModifier) -> F::Result { - let bound = TyParamBound::Trait(poly_trait, modifier); - self.callback.invoke(bound) - } - - pub fn trait_

(self, path: P) -> PolyTraitRefBuilder> - where P: IntoPath - { - let builder = TraitTyParamBoundBuilder { - builder: self, - modifier: TraitBoundModifier::None, - }; - - PolyTraitRefBuilder::with_callback(path, builder) - } - - pub fn maybe_trait

(self, path: P) -> PolyTraitRefBuilder> - where P: IntoPath - { - let builder = TraitTyParamBoundBuilder { - builder: self, - modifier: TraitBoundModifier::Maybe, - }; - - PolyTraitRefBuilder::with_callback(path, builder) - } - - pub fn iterator(self, ty: Ty) -> PolyTraitRefBuilder> { - let path = PathBuilder::new() - .global() - .id("std") - .id("iter") - .segment("Iterator") - .binding("Item") - .build(ty) - .build() - .build(); - self.trait_(path) - } - - pub fn lifetime(self, lifetime: L) -> F::Result - where L: IntoLifetime - { - let lifetime = lifetime.into_lifetime(); - self.callback.invoke(TyParamBound::Region(lifetime)) - } -} - -// //////////////////////////////////////////////////////////////////////////// - -pub struct TraitTyParamBoundBuilder { - builder: TyParamBoundBuilder, - modifier: TraitBoundModifier, -} - -impl Invoke for TraitTyParamBoundBuilder - where F: Invoke -{ - type Result = F::Result; - - fn invoke(self, poly_trait: PolyTraitRef) -> Self::Result { - self.builder.build_trait(poly_trait, self.modifier) - } -} - -// //////////////////////////////////////////////////////////////////////////// - -pub struct PolyTraitRefBuilder { - callback: F, - trait_ref: Path, - lifetimes: Vec, -} - -impl PolyTraitRefBuilder - where F: Invoke -{ - pub fn with_callback

(path: P, callback: F) -> Self - where P: IntoPath - { - PolyTraitRefBuilder { - callback: callback, - trait_ref: path.into_path(), - lifetimes: Vec::new(), - } - } - - pub fn with_lifetime(mut self, lifetime: L) -> Self - where L: IntoLifetimeDef - { - self.lifetimes.push(lifetime.into_lifetime_def()); - self - } - - pub fn lifetime(self, name: N) -> LifetimeDefBuilder - where N: Into - { - LifetimeDefBuilder::with_callback(name, self) - } - - pub fn build(self) -> F::Result { - self.callback.invoke(PolyTraitRef { - bound_lifetimes: self.lifetimes, - trait_ref: self.trait_ref, - }) - } -} - -impl Invoke for PolyTraitRefBuilder - where F: Invoke -{ - type Result = Self; - - fn invoke(self, lifetime: LifetimeDef) -> Self { - self.with_lifetime(lifetime) - } -} diff --git a/third_party/rust/syn-0.10.8/src/aster/where_predicate.rs b/third_party/rust/syn-0.10.8/src/aster/where_predicate.rs deleted file mode 100644 index 611d058f6718..000000000000 --- a/third_party/rust/syn-0.10.8/src/aster/where_predicate.rs +++ /dev/null @@ -1,259 +0,0 @@ -use {Ident, Lifetime, LifetimeDef, Ty, TyParamBound, WhereBoundPredicate, WherePredicate, - WhereRegionPredicate}; -use aster::invoke::{Invoke, Identity}; -use aster::lifetime::{IntoLifetime, IntoLifetimeDef, LifetimeDefBuilder}; -use aster::path::IntoPath; -use aster::ty::TyBuilder; -use aster::ty_param::{TyParamBoundBuilder, PolyTraitRefBuilder, TraitTyParamBoundBuilder}; - -// //////////////////////////////////////////////////////////////////////////// - -pub struct WherePredicateBuilder { - callback: F, -} - -impl WherePredicateBuilder { - pub fn new() -> Self { - WherePredicateBuilder::with_callback(Identity) - } -} - -impl WherePredicateBuilder - where F: Invoke -{ - pub fn with_callback(callback: F) -> Self { - WherePredicateBuilder { callback: callback } - } - - pub fn bound(self) -> TyBuilder { - TyBuilder::with_callback(self) - } - - pub fn lifetime(self, lifetime: L) -> WhereRegionPredicateBuilder - where L: IntoLifetime - { - WhereRegionPredicateBuilder { - callback: self.callback, - lifetime: lifetime.into_lifetime(), - bounds: Vec::new(), - } - } -} - -impl Invoke for WherePredicateBuilder - where F: Invoke -{ - type Result = WhereBoundPredicateTyBuilder; - - fn invoke(self, ty: Ty) -> Self::Result { - WhereBoundPredicateTyBuilder { - callback: self.callback, - ty: ty, - bound_lifetimes: Vec::new(), - } - } -} - -// //////////////////////////////////////////////////////////////////////////// - -pub struct WhereBoundPredicateBuilder { - callback: F, -} - -impl Invoke for WhereBoundPredicateBuilder - where F: Invoke -{ - type Result = WhereBoundPredicateTyBuilder; - - fn invoke(self, ty: Ty) -> Self::Result { - WhereBoundPredicateTyBuilder { - callback: self.callback, - ty: ty, - bound_lifetimes: Vec::new(), - } - } -} - -// //////////////////////////////////////////////////////////////////////////// - -pub struct WhereBoundPredicateTyBuilder { - callback: F, - ty: Ty, - bound_lifetimes: Vec, -} - -impl WhereBoundPredicateTyBuilder - where F: Invoke -{ - pub fn with_for_lifetime(mut self, lifetime: L) -> Self - where L: IntoLifetimeDef - { - self.bound_lifetimes.push(lifetime.into_lifetime_def()); - self - } - - pub fn for_lifetime(self, name: N) -> LifetimeDefBuilder - where N: Into - { - LifetimeDefBuilder::with_callback(name, self) - } - - pub fn with_bound(self, bound: TyParamBound) -> WhereBoundPredicateTyBoundsBuilder { - WhereBoundPredicateTyBoundsBuilder { - callback: self.callback, - ty: self.ty, - bound_lifetimes: self.bound_lifetimes, - bounds: vec![bound], - } - } - - pub fn bound(self) -> TyParamBoundBuilder> { - let builder = WhereBoundPredicateTyBoundsBuilder { - callback: self.callback, - ty: self.ty, - bound_lifetimes: self.bound_lifetimes, - bounds: vec![], - }; - TyParamBoundBuilder::with_callback(builder) - } - - pub fn trait_

- (self, - path: P) - -> PolyTraitRefBuilder>> - where P: IntoPath - { - self.bound().trait_(path) - } - - pub fn lifetime(self, lifetime: L) -> WhereBoundPredicateTyBoundsBuilder - where L: IntoLifetime - { - self.bound().lifetime(lifetime) - } -} - -impl Invoke for WhereBoundPredicateTyBuilder - where F: Invoke -{ - type Result = Self; - - fn invoke(self, lifetime: LifetimeDef) -> Self { - self.with_for_lifetime(lifetime) - } -} - -impl Invoke for WhereBoundPredicateTyBuilder - where F: Invoke -{ - type Result = WhereBoundPredicateTyBoundsBuilder; - - fn invoke(self, bound: TyParamBound) -> Self::Result { - self.with_bound(bound) - } -} - -// //////////////////////////////////////////////////////////////////////////// - -pub struct WhereBoundPredicateTyBoundsBuilder { - callback: F, - ty: Ty, - bound_lifetimes: Vec, - bounds: Vec, -} - -impl WhereBoundPredicateTyBoundsBuilder - where F: Invoke -{ - pub fn with_for_lifetime(mut self, lifetime: L) -> Self - where L: IntoLifetimeDef - { - self.bound_lifetimes.push(lifetime.into_lifetime_def()); - self - } - - pub fn for_lifetime(self, name: N) -> LifetimeDefBuilder - where N: Into - { - LifetimeDefBuilder::with_callback(name, self) - } - - pub fn with_bound(mut self, bound: TyParamBound) -> Self { - self.bounds.push(bound); - self - } - - pub fn bound(self) -> TyParamBoundBuilder { - TyParamBoundBuilder::with_callback(self) - } - - pub fn trait_

(self, path: P) -> PolyTraitRefBuilder> - where P: IntoPath - { - self.bound().trait_(path) - } - - pub fn lifetime(self, lifetime: L) -> Self - where L: IntoLifetime - { - self.bound().lifetime(lifetime) - } - - pub fn build(self) -> F::Result { - let predicate = WhereBoundPredicate { - bound_lifetimes: self.bound_lifetimes, - bounded_ty: self.ty, - bounds: self.bounds, - }; - - self.callback.invoke(WherePredicate::BoundPredicate(predicate)) - } -} - -impl Invoke for WhereBoundPredicateTyBoundsBuilder - where F: Invoke -{ - type Result = Self; - - fn invoke(self, lifetime: LifetimeDef) -> Self { - self.with_for_lifetime(lifetime) - } -} - -impl Invoke for WhereBoundPredicateTyBoundsBuilder - where F: Invoke -{ - type Result = Self; - - fn invoke(self, bound: TyParamBound) -> Self { - self.with_bound(bound) - } -} - -// //////////////////////////////////////////////////////////////////////////// - -pub struct WhereRegionPredicateBuilder { - callback: F, - lifetime: Lifetime, - bounds: Vec, -} - -impl WhereRegionPredicateBuilder - where F: Invoke -{ - pub fn bound(mut self, lifetime: L) -> Self - where L: IntoLifetime - { - self.bounds.push(lifetime.into_lifetime()); - self - } - - pub fn build(self) -> F::Result { - let predicate = WhereRegionPredicate { - lifetime: self.lifetime, - bounds: self.bounds, - }; - - self.callback.invoke(WherePredicate::RegionPredicate(predicate)) - } -} diff --git a/third_party/rust/syn-0.10.8/src/attr.rs b/third_party/rust/syn-0.10.8/src/attr.rs deleted file mode 100644 index 146427a8fd8a..000000000000 --- a/third_party/rust/syn-0.10.8/src/attr.rs +++ /dev/null @@ -1,293 +0,0 @@ -use super::*; - -use std::iter; - -/// Doc-comments are promoted to attributes that have `is_sugared_doc` = true -#[derive(Debug, Clone, Eq, PartialEq, Hash)] -pub struct Attribute { - pub style: AttrStyle, - pub value: MetaItem, - pub is_sugared_doc: bool, -} - -impl Attribute { - pub fn name(&self) -> &str { - self.value.name() - } -} - -/// Distinguishes between Attributes that decorate items and Attributes that -/// are contained as statements within items. These two cases need to be -/// distinguished for pretty-printing. -#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] -pub enum AttrStyle { - Outer, - Inner, -} - -/// A compile-time attribute item. -/// -/// E.g. `#[test]`, `#[derive(..)]` or `#[feature = "foo"]` -#[derive(Debug, Clone, Eq, PartialEq, Hash)] -pub enum MetaItem { - /// Word meta item. - /// - /// E.g. `test` as in `#[test]` - Word(Ident), - /// List meta item. - /// - /// E.g. `derive(..)` as in `#[derive(..)]` - List(Ident, Vec), - /// Name value meta item. - /// - /// E.g. `feature = "foo"` as in `#[feature = "foo"]` - NameValue(Ident, Lit), -} - -impl MetaItem { - pub fn name(&self) -> &str { - match *self { - MetaItem::Word(ref name) | - MetaItem::List(ref name, _) | - MetaItem::NameValue(ref name, _) => name.as_ref(), - } - } -} - -/// Possible values inside of compile-time attribute lists. -/// -/// E.g. the '..' in `#[name(..)]`. -#[derive(Debug, Clone, Eq, PartialEq, Hash)] -pub enum NestedMetaItem { - /// A full MetaItem, for recursive meta items. - MetaItem(MetaItem), - /// A literal. - /// - /// E.g. "foo", 64, true - Literal(Lit), -} - -pub trait FilterAttrs<'a> { - type Ret: Iterator; - - fn outer(self) -> Self::Ret; - fn inner(self) -> Self::Ret; -} - -impl<'a, T> FilterAttrs<'a> for T - where T: IntoIterator -{ - type Ret = iter::Filter bool>; - - fn outer(self) -> Self::Ret { - fn is_outer(attr: &&Attribute) -> bool { - attr.style == AttrStyle::Outer - } - self.into_iter().filter(is_outer) - } - - fn inner(self) -> Self::Ret { - fn is_inner(attr: &&Attribute) -> bool { - attr.style == AttrStyle::Inner - } - self.into_iter().filter(is_inner) - } -} - -#[cfg(feature = "parsing")] -pub mod parsing { - use super::*; - use ident::parsing::ident; - use lit::parsing::lit; - use space::{block_comment, whitespace}; - - #[cfg(feature = "full")] - named!(pub inner_attr -> Attribute, alt!( - do_parse!( - punct!("#") >> - punct!("!") >> - punct!("[") >> - meta_item: meta_item >> - punct!("]") >> - (Attribute { - style: AttrStyle::Inner, - value: meta_item, - is_sugared_doc: false, - }) - ) - | - do_parse!( - punct!("//!") >> - content: take_until!("\n") >> - (Attribute { - style: AttrStyle::Inner, - value: MetaItem::NameValue( - "doc".into(), - format!("//!{}", content).into(), - ), - is_sugared_doc: true, - }) - ) - | - do_parse!( - option!(whitespace) >> - peek!(tag!("/*!")) >> - com: block_comment >> - (Attribute { - style: AttrStyle::Inner, - value: MetaItem::NameValue( - "doc".into(), - com.into(), - ), - is_sugared_doc: true, - }) - ) - )); - - named!(pub outer_attr -> Attribute, alt!( - do_parse!( - punct!("#") >> - punct!("[") >> - meta_item: meta_item >> - punct!("]") >> - (Attribute { - style: AttrStyle::Outer, - value: meta_item, - is_sugared_doc: false, - }) - ) - | - do_parse!( - punct!("///") >> - not!(peek!(tag!("/"))) >> - content: take_until!("\n") >> - (Attribute { - style: AttrStyle::Outer, - value: MetaItem::NameValue( - "doc".into(), - format!("///{}", content).into(), - ), - is_sugared_doc: true, - }) - ) - | - do_parse!( - option!(whitespace) >> - peek!(tuple!(tag!("/**"), not!(tag!("*")))) >> - com: block_comment >> - (Attribute { - style: AttrStyle::Outer, - value: MetaItem::NameValue( - "doc".into(), - com.into(), - ), - is_sugared_doc: true, - }) - ) - )); - - named!(meta_item -> MetaItem, alt!( - do_parse!( - id: ident >> - punct!("(") >> - inner: terminated_list!(punct!(","), nested_meta_item) >> - punct!(")") >> - (MetaItem::List(id, inner)) - ) - | - do_parse!( - name: ident >> - punct!("=") >> - value: lit >> - (MetaItem::NameValue(name, value)) - ) - | - map!(ident, MetaItem::Word) - )); - - named!(nested_meta_item -> NestedMetaItem, alt!( - meta_item => { NestedMetaItem::MetaItem } - | - lit => { NestedMetaItem::Literal } - )); -} - -#[cfg(feature = "printing")] -mod printing { - use super::*; - use lit::{Lit, StrStyle}; - use quote::{Tokens, ToTokens}; - - impl ToTokens for Attribute { - fn to_tokens(&self, tokens: &mut Tokens) { - if let Attribute { style, - value: MetaItem::NameValue(ref name, - Lit::Str(ref value, StrStyle::Cooked)), - is_sugared_doc: true } = *self { - if name == "doc" { - match style { - AttrStyle::Inner if value.starts_with("//!") => { - tokens.append(&format!("{}\n", value)); - return; - } - AttrStyle::Inner if value.starts_with("/*!") => { - tokens.append(value); - return; - } - AttrStyle::Outer if value.starts_with("///") => { - tokens.append(&format!("{}\n", value)); - return; - } - AttrStyle::Outer if value.starts_with("/**") => { - tokens.append(value); - return; - } - _ => {} - } - } - } - - tokens.append("#"); - if let AttrStyle::Inner = self.style { - tokens.append("!"); - } - tokens.append("["); - self.value.to_tokens(tokens); - tokens.append("]"); - } - } - - impl ToTokens for MetaItem { - fn to_tokens(&self, tokens: &mut Tokens) { - match *self { - MetaItem::Word(ref ident) => { - ident.to_tokens(tokens); - } - MetaItem::List(ref ident, ref inner) => { - ident.to_tokens(tokens); - tokens.append("("); - tokens.append_separated(inner, ","); - tokens.append(")"); - } - MetaItem::NameValue(ref name, ref value) => { - name.to_tokens(tokens); - tokens.append("="); - value.to_tokens(tokens); - } - } - } - } - - impl ToTokens for NestedMetaItem { - fn to_tokens(&self, tokens: &mut Tokens) { - match *self { - NestedMetaItem::MetaItem(ref nested) => { - nested.to_tokens(tokens); - } - NestedMetaItem::Literal(ref lit) => { - lit.to_tokens(tokens); - } - } - } - } -} diff --git a/third_party/rust/syn-0.10.8/src/constant.rs b/third_party/rust/syn-0.10.8/src/constant.rs deleted file mode 100644 index c7d0e32e0816..000000000000 --- a/third_party/rust/syn-0.10.8/src/constant.rs +++ /dev/null @@ -1,167 +0,0 @@ -use super::*; - -#[derive(Debug, Clone, Eq, PartialEq, Hash)] -pub enum ConstExpr { - /// A function call - /// - /// The first field resolves to the function itself, - /// and the second field is the list of arguments - Call(Box, Vec), - /// A binary operation (For example: `a + b`, `a * b`) - Binary(BinOp, Box, Box), - /// A unary operation (For example: `!x`, `*x`) - Unary(UnOp, Box), - /// A literal (For example: `1`, `"foo"`) - Lit(Lit), - /// A cast (`foo as f64`) - Cast(Box, Box), - /// Variable reference, possibly containing `::` and/or type - /// parameters, e.g. foo::bar::. - Path(Path), - /// An indexing operation (`foo[2]`) - Index(Box, Box), - /// No-op: used solely so we can pretty-print faithfully - Paren(Box), - /// If compiling with full support for expression syntax, any expression is - /// allowed - Other(Other), -} - -#[cfg(not(feature = "full"))] -#[derive(Debug, Clone, Eq, PartialEq, Hash)] -pub struct Other { - _private: (), -} - -#[cfg(feature = "full")] -pub type Other = Expr; - -#[cfg(feature = "parsing")] -pub mod parsing { - use super::*; - use {BinOp, Ty}; - use lit::parsing::lit; - use op::parsing::{binop, unop}; - use ty::parsing::{path, ty}; - - named!(pub const_expr -> ConstExpr, do_parse!( - mut e: alt!( - expr_unary - | - expr_lit - | - expr_path - | - expr_paren - ) >> - many0!(alt!( - tap!(args: and_call => { - e = ConstExpr::Call(Box::new(e), args); - }) - | - tap!(more: and_binary => { - let (op, other) = more; - e = ConstExpr::Binary(op, Box::new(e), Box::new(other)); - }) - | - tap!(ty: and_cast => { - e = ConstExpr::Cast(Box::new(e), Box::new(ty)); - }) - | - tap!(i: and_index => { - e = ConstExpr::Index(Box::new(e), Box::new(i)); - }) - )) >> - (e) - )); - - named!(and_call -> Vec, do_parse!( - punct!("(") >> - args: terminated_list!(punct!(","), const_expr) >> - punct!(")") >> - (args) - )); - - named!(and_binary -> (BinOp, ConstExpr), tuple!(binop, const_expr)); - - named!(expr_unary -> ConstExpr, do_parse!( - operator: unop >> - operand: const_expr >> - (ConstExpr::Unary(operator, Box::new(operand))) - )); - - named!(expr_lit -> ConstExpr, map!(lit, ConstExpr::Lit)); - - named!(expr_path -> ConstExpr, map!(path, ConstExpr::Path)); - - named!(and_index -> ConstExpr, delimited!(punct!("["), const_expr, punct!("]"))); - - named!(expr_paren -> ConstExpr, do_parse!( - punct!("(") >> - e: const_expr >> - punct!(")") >> - (ConstExpr::Paren(Box::new(e))) - )); - - named!(and_cast -> Ty, do_parse!( - keyword!("as") >> - ty: ty >> - (ty) - )); -} - -#[cfg(feature = "printing")] -mod printing { - use super::*; - use quote::{Tokens, ToTokens}; - - impl ToTokens for ConstExpr { - fn to_tokens(&self, tokens: &mut Tokens) { - match *self { - ConstExpr::Call(ref func, ref args) => { - func.to_tokens(tokens); - tokens.append("("); - tokens.append_separated(args, ","); - tokens.append(")"); - } - ConstExpr::Binary(op, ref left, ref right) => { - left.to_tokens(tokens); - op.to_tokens(tokens); - right.to_tokens(tokens); - } - ConstExpr::Unary(op, ref expr) => { - op.to_tokens(tokens); - expr.to_tokens(tokens); - } - ConstExpr::Lit(ref lit) => lit.to_tokens(tokens), - ConstExpr::Cast(ref expr, ref ty) => { - expr.to_tokens(tokens); - tokens.append("as"); - ty.to_tokens(tokens); - } - ConstExpr::Path(ref path) => path.to_tokens(tokens), - ConstExpr::Index(ref expr, ref index) => { - expr.to_tokens(tokens); - tokens.append("["); - index.to_tokens(tokens); - tokens.append("]"); - } - ConstExpr::Paren(ref expr) => { - tokens.append("("); - expr.to_tokens(tokens); - tokens.append(")"); - } - ConstExpr::Other(ref other) => { - other.to_tokens(tokens); - } - } - } - } - - #[cfg(not(feature = "full"))] - impl ToTokens for Other { - fn to_tokens(&self, _tokens: &mut Tokens) { - unreachable!() - } - } -} diff --git a/third_party/rust/syn-0.10.8/src/data.rs b/third_party/rust/syn-0.10.8/src/data.rs deleted file mode 100644 index 7ccfd7a6885f..000000000000 --- a/third_party/rust/syn-0.10.8/src/data.rs +++ /dev/null @@ -1,245 +0,0 @@ -use super::*; - -#[derive(Debug, Clone, Eq, PartialEq, Hash)] -pub struct Variant { - pub ident: Ident, - pub attrs: Vec, - pub data: VariantData, - /// Explicit discriminant, e.g. `Foo = 1` - pub discriminant: Option, -} - -#[derive(Debug, Clone, Eq, PartialEq, Hash)] -pub enum VariantData { - Struct(Vec), - Tuple(Vec), - Unit, -} - -impl VariantData { - pub fn fields(&self) -> &[Field] { - match *self { - VariantData::Struct(ref fields) | - VariantData::Tuple(ref fields) => fields, - VariantData::Unit => &[], - } - } - - pub fn fields_mut(&mut self) -> &mut [Field] { - match *self { - VariantData::Struct(ref mut fields) | - VariantData::Tuple(ref mut fields) => fields, - VariantData::Unit => &mut [], - } - } -} - -#[derive(Debug, Clone, Eq, PartialEq, Hash)] -pub struct Field { - pub ident: Option, - pub vis: Visibility, - pub attrs: Vec, - pub ty: Ty, -} - -#[derive(Debug, Clone, Eq, PartialEq, Hash)] -pub enum Visibility { - Public, - Crate, - Restricted(Box), - Inherited, -} - -#[cfg(feature = "parsing")] -pub mod parsing { - use super::*; - use WhereClause; - use attr::parsing::outer_attr; - use constant::parsing::const_expr; - use generics::parsing::where_clause; - use ident::parsing::ident; - use ty::parsing::{path, ty}; - - named!(pub struct_body -> (WhereClause, VariantData), alt!( - do_parse!( - wh: where_clause >> - body: struct_like_body >> - (wh, VariantData::Struct(body)) - ) - | - do_parse!( - body: tuple_like_body >> - wh: where_clause >> - punct!(";") >> - (wh, VariantData::Tuple(body)) - ) - | - do_parse!( - wh: where_clause >> - punct!(";") >> - (wh, VariantData::Unit) - ) - )); - - named!(pub enum_body -> (WhereClause, Vec), do_parse!( - wh: where_clause >> - punct!("{") >> - variants: terminated_list!(punct!(","), variant) >> - punct!("}") >> - (wh, variants) - )); - - named!(variant -> Variant, do_parse!( - attrs: many0!(outer_attr) >> - id: ident >> - data: alt!( - struct_like_body => { VariantData::Struct } - | - tuple_like_body => { VariantData::Tuple } - | - epsilon!() => { |_| VariantData::Unit } - ) >> - disr: option!(preceded!(punct!("="), const_expr)) >> - (Variant { - ident: id, - attrs: attrs, - data: data, - discriminant: disr, - }) - )); - - named!(pub struct_like_body -> Vec, do_parse!( - punct!("{") >> - fields: terminated_list!(punct!(","), struct_field) >> - punct!("}") >> - (fields) - )); - - named!(tuple_like_body -> Vec, do_parse!( - punct!("(") >> - fields: terminated_list!(punct!(","), tuple_field) >> - punct!(")") >> - (fields) - )); - - named!(struct_field -> Field, do_parse!( - attrs: many0!(outer_attr) >> - vis: visibility >> - id: ident >> - punct!(":") >> - ty: ty >> - (Field { - ident: Some(id), - vis: vis, - attrs: attrs, - ty: ty, - }) - )); - - named!(tuple_field -> Field, do_parse!( - attrs: many0!(outer_attr) >> - vis: visibility >> - ty: ty >> - (Field { - ident: None, - vis: vis, - attrs: attrs, - ty: ty, - }) - )); - - named!(pub visibility -> Visibility, alt!( - do_parse!( - keyword!("pub") >> - punct!("(") >> - keyword!("crate") >> - punct!(")") >> - (Visibility::Crate) - ) - | - do_parse!( - keyword!("pub") >> - punct!("(") >> - restricted: path >> - punct!(")") >> - (Visibility::Restricted(Box::new(restricted))) - ) - | - keyword!("pub") => { |_| Visibility::Public } - | - epsilon!() => { |_| Visibility::Inherited } - )); -} - -#[cfg(feature = "printing")] -mod printing { - use super::*; - use quote::{Tokens, ToTokens}; - - impl ToTokens for Variant { - fn to_tokens(&self, tokens: &mut Tokens) { - for attr in &self.attrs { - attr.to_tokens(tokens); - } - self.ident.to_tokens(tokens); - self.data.to_tokens(tokens); - if let Some(ref disr) = self.discriminant { - tokens.append("="); - disr.to_tokens(tokens); - } - } - } - - impl ToTokens for VariantData { - fn to_tokens(&self, tokens: &mut Tokens) { - match *self { - VariantData::Struct(ref fields) => { - tokens.append("{"); - tokens.append_separated(fields, ","); - tokens.append("}"); - } - VariantData::Tuple(ref fields) => { - tokens.append("("); - tokens.append_separated(fields, ","); - tokens.append(")"); - } - VariantData::Unit => {} - } - } - } - - impl ToTokens for Field { - fn to_tokens(&self, tokens: &mut Tokens) { - for attr in &self.attrs { - attr.to_tokens(tokens); - } - self.vis.to_tokens(tokens); - if let Some(ref ident) = self.ident { - ident.to_tokens(tokens); - tokens.append(":"); - } - self.ty.to_tokens(tokens); - } - } - - impl ToTokens for Visibility { - fn to_tokens(&self, tokens: &mut Tokens) { - match *self { - Visibility::Public => tokens.append("pub"), - Visibility::Crate => { - tokens.append("pub"); - tokens.append("("); - tokens.append("crate"); - tokens.append(")"); - } - Visibility::Restricted(ref path) => { - tokens.append("pub"); - tokens.append("("); - path.to_tokens(tokens); - tokens.append(")"); - } - Visibility::Inherited => {} - } - } - } -} diff --git a/third_party/rust/syn-0.10.8/src/escape.rs b/third_party/rust/syn-0.10.8/src/escape.rs deleted file mode 100644 index d8831ebdb620..000000000000 --- a/third_party/rust/syn-0.10.8/src/escape.rs +++ /dev/null @@ -1,292 +0,0 @@ -use std::{char, str}; -use std::num::ParseIntError; -use nom::IResult; - -pub fn cooked_string(input: &str) -> IResult<&str, String> { - let mut s = String::new(); - let mut chars = input.char_indices().peekable(); - while let Some((byte_offset, ch)) = chars.next() { - match ch { - '"' => { - return IResult::Done(&input[byte_offset..], s); - } - '\r' => { - if let Some((_, '\n')) = chars.next() { - s.push('\n'); - } else { - break; - } - } - '\\' => { - match chars.next() { - Some((_, 'x')) => { - match backslash_x_char(&mut chars) { - Some(ch) => s.push(ch), - None => break, - } - } - Some((_, 'n')) => s.push('\n'), - Some((_, 'r')) => s.push('\r'), - Some((_, 't')) => s.push('\t'), - Some((_, '\\')) => s.push('\\'), - Some((_, '0')) => s.push('\0'), - Some((_, 'u')) => { - match backslash_u(&mut chars) { - Some(ch) => s.push(ch), - None => break, - } - } - Some((_, '\'')) => s.push('\''), - Some((_, '"')) => s.push('"'), - Some((_, '\n')) | Some((_, '\r')) => { - while let Some(&(_, ch)) = chars.peek() { - if ch.is_whitespace() { - chars.next(); - } else { - break; - } - } - } - _ => break, - } - } - ch => { - s.push(ch); - } - } - } - IResult::Error -} - -pub fn cooked_byte_string(mut input: &str) -> IResult<&str, Vec> { - let mut vec = Vec::new(); - let mut bytes = input.bytes().enumerate(); - 'outer: while let Some((offset, b)) = bytes.next() { - match b { - b'"' => { - return IResult::Done(&input[offset..], vec); - } - b'\r' => { - if let Some((_, b'\n')) = bytes.next() { - vec.push(b'\n'); - } else { - break; - } - } - b'\\' => { - match bytes.next() { - Some((_, b'x')) => { - match backslash_x_byte(&mut bytes) { - Some(b) => vec.push(b), - None => break, - } - } - Some((_, b'n')) => vec.push(b'\n'), - Some((_, b'r')) => vec.push(b'\r'), - Some((_, b't')) => vec.push(b'\t'), - Some((_, b'\\')) => vec.push(b'\\'), - Some((_, b'0')) => vec.push(b'\0'), - Some((_, b'\'')) => vec.push(b'\''), - Some((_, b'"')) => vec.push(b'"'), - Some((newline, b'\n')) | - Some((newline, b'\r')) => { - let rest = &input[newline + 1..]; - for (offset, ch) in rest.char_indices() { - if !ch.is_whitespace() { - input = &rest[offset..]; - bytes = input.bytes().enumerate(); - continue 'outer; - } - } - break; - } - _ => break, - } - } - b if b < 0x80 => { - vec.push(b); - } - _ => break, - } - } - IResult::Error -} - -pub fn cooked_char(input: &str) -> IResult<&str, char> { - let mut chars = input.char_indices(); - let ch = match chars.next().map(|(_, ch)| ch) { - Some('\\') => { - match chars.next().map(|(_, ch)| ch) { - Some('x') => backslash_x_char(&mut chars), - Some('n') => Some('\n'), - Some('r') => Some('\r'), - Some('t') => Some('\t'), - Some('\\') => Some('\\'), - Some('0') => Some('\0'), - Some('u') => backslash_u(&mut chars), - Some('\'') => Some('\''), - Some('"') => Some('"'), - _ => None, - } - } - ch => ch, - }; - match ch { - Some(ch) => IResult::Done(chars.as_str(), ch), - None => IResult::Error, - } -} - -pub fn cooked_byte(input: &str) -> IResult<&str, u8> { - let mut bytes = input.bytes().enumerate(); - let b = match bytes.next().map(|(_, b)| b) { - Some(b'\\') => { - match bytes.next().map(|(_, b)| b) { - Some(b'x') => backslash_x_byte(&mut bytes), - Some(b'n') => Some(b'\n'), - Some(b'r') => Some(b'\r'), - Some(b't') => Some(b'\t'), - Some(b'\\') => Some(b'\\'), - Some(b'0') => Some(b'\0'), - Some(b'\'') => Some(b'\''), - Some(b'"') => Some(b'"'), - _ => None, - } - } - b => b, - }; - match b { - Some(b) => { - match bytes.next() { - Some((offset, _)) => IResult::Done(&input[offset..], b), - None => IResult::Done("", b), - } - } - None => IResult::Error, - } -} - -pub fn raw_string(input: &str) -> IResult<&str, (String, usize)> { - let mut chars = input.char_indices(); - let mut n = 0; - while let Some((byte_offset, ch)) = chars.next() { - match ch { - '"' => { - n = byte_offset; - break; - } - '#' => {} - _ => return IResult::Error, - } - } - let mut s = String::new(); - for (byte_offset, ch) in chars { - match ch { - '"' if input[byte_offset + 1..].starts_with(&input[..n]) => { - let rest = &input[byte_offset + 1 + n..]; - return IResult::Done(rest, (s, n)); - } - '\r' => {} - _ => s.push(ch), - } - } - IResult::Error -} - -macro_rules! next_ch { - ($chars:ident @ $pat:pat $(| $rest:pat)*) => { - match $chars.next() { - Some((_, ch)) => match ch { - $pat $(| $rest)* => ch, - _ => return None, - }, - None => return None, - } - }; -} - -trait FromStrRadix: Sized { - fn from_str_radix(src: &str, radix: u32) -> Result; -} - -impl FromStrRadix for u8 { - fn from_str_radix(src: &str, radix: u32) -> Result { - u8::from_str_radix(src, radix) - } -} - -impl FromStrRadix for u32 { - fn from_str_radix(src: &str, radix: u32) -> Result { - u32::from_str_radix(src, radix) - } -} - -macro_rules! from_hex { - ($($ch:ident)+) => {{ - let hex_bytes = &[$($ch as u8),*]; - let hex_str = str::from_utf8(hex_bytes).unwrap(); - FromStrRadix::from_str_radix(hex_str, 16).unwrap() - }}; -} - -#[cfg_attr(feature = "clippy", allow(diverging_sub_expression))] -fn backslash_x_char(chars: &mut I) -> Option - where I: Iterator -{ - let a = next_ch!(chars @ '0'...'7'); - let b = next_ch!(chars @ '0'...'9' | 'a'...'f' | 'A'...'F'); - char::from_u32(from_hex!(a b)) -} - -#[cfg_attr(feature = "clippy", allow(diverging_sub_expression))] -fn backslash_x_byte(chars: &mut I) -> Option - where I: Iterator -{ - let a = next_ch!(chars @ b'0'...b'9' | b'a'...b'f' | b'A'...b'F'); - let b = next_ch!(chars @ b'0'...b'9' | b'a'...b'f' | b'A'...b'F'); - Some(from_hex!(a b)) -} - -#[cfg_attr(feature = "clippy", allow(diverging_sub_expression, many_single_char_names))] -fn backslash_u(chars: &mut I) -> Option - where I: Iterator -{ - next_ch!(chars @ '{'); - let a = next_ch!(chars @ '0'...'9' | 'a'...'f' | 'A'...'F'); - let b = next_ch!(chars @ '0'...'9' | 'a'...'f' | 'A'...'F' | '}'); - if b == '}' { - return char::from_u32(from_hex!(a)); - } - let c = next_ch!(chars @ '0'...'9' | 'a'...'f' | 'A'...'F' | '}'); - if c == '}' { - return char::from_u32(from_hex!(a b)); - } - let d = next_ch!(chars @ '0'...'9' | 'a'...'f' | 'A'...'F' | '}'); - if d == '}' { - return char::from_u32(from_hex!(a b c)); - } - let e = next_ch!(chars @ '0'...'9' | 'a'...'f' | 'A'...'F' | '}'); - if e == '}' { - return char::from_u32(from_hex!(a b c d)); - } - let f = next_ch!(chars @ '0'...'9' | 'a'...'f' | 'A'...'F' | '}'); - if f == '}' { - return char::from_u32(from_hex!(a b c d e)); - } - next_ch!(chars @ '}'); - char::from_u32(from_hex!(a b c d e f)) -} - -#[test] -fn test_cooked_string() { - let input = "\\x62 \\\n \\u{7} \\u{64} \\u{bf5} \\u{12ba} \\u{1F395} \\u{102345}\""; - let expected = "\x62 \u{7} \u{64} \u{bf5} \u{12ba} \u{1F395} \u{102345}"; - assert_eq!(cooked_string(input), IResult::Done("\"", expected.to_string())); -} - -#[test] -fn test_cooked_byte_string() { - let input = "\\x62 \\\n \\xEF\""; - let expected = b"\x62 \xEF"; - assert_eq!(cooked_byte_string(input), IResult::Done("\"", expected.to_vec())); -} diff --git a/third_party/rust/syn-0.10.8/src/expr.rs b/third_party/rust/syn-0.10.8/src/expr.rs deleted file mode 100644 index c8b574d90efd..000000000000 --- a/third_party/rust/syn-0.10.8/src/expr.rs +++ /dev/null @@ -1,1701 +0,0 @@ -use super::*; - -#[derive(Debug, Clone, Eq, PartialEq, Hash)] -pub struct Expr { - pub node: ExprKind, - pub attrs: Vec, -} - -impl From for Expr { - fn from(node: ExprKind) -> Expr { - Expr { - node: node, - attrs: Vec::new(), - } - } -} - -#[derive(Debug, Clone, Eq, PartialEq, Hash)] -pub enum ExprKind { - /// A `box x` expression. - Box(Box), - /// First expr is the place; second expr is the value. - InPlace(Box, Box), - /// An array (`[a, b, c, d]`) - Vec(Vec), - /// A function call - /// - /// The first field resolves to the function itself, - /// and the second field is the list of arguments - Call(Box, Vec), - /// A method call (`x.foo::(a, b, c, d)`) - /// - /// The `Ident` is the identifier for the method name. - /// The vector of `Ty`s are the ascripted type parameters for the method - /// (within the angle brackets). - /// - /// The first element of the vector of `Expr`s is the expression that evaluates - /// to the object on which the method is being called on (the receiver), - /// and the remaining elements are the rest of the arguments. - /// - /// Thus, `x.foo::(a, b, c, d)` is represented as - /// `ExprKind::MethodCall(foo, [Bar, Baz], [x, a, b, c, d])`. - MethodCall(Ident, Vec, Vec), - /// A tuple (`(a, b, c, d)`) - Tup(Vec), - /// A binary operation (For example: `a + b`, `a * b`) - Binary(BinOp, Box, Box), - /// A unary operation (For example: `!x`, `*x`) - Unary(UnOp, Box), - /// A literal (For example: `1`, `"foo"`) - Lit(Lit), - /// A cast (`foo as f64`) - Cast(Box, Box), - /// Type ascription (`foo: f64`) - Type(Box, Box), - /// An `if` block, with an optional else block - /// - /// `if expr { block } else { expr }` - If(Box, Block, Option>), - /// An `if let` expression with an optional else block - /// - /// `if let pat = expr { block } else { expr }` - /// - /// This is desugared to a `match` expression. - IfLet(Box, Box, Block, Option>), - /// A while loop, with an optional label - /// - /// `'label: while expr { block }` - While(Box, Block, Option), - /// A while-let loop, with an optional label - /// - /// `'label: while let pat = expr { block }` - /// - /// This is desugared to a combination of `loop` and `match` expressions. - WhileLet(Box, Box, Block, Option), - /// A for loop, with an optional label - /// - /// `'label: for pat in expr { block }` - /// - /// This is desugared to a combination of `loop` and `match` expressions. - ForLoop(Box, Box, Block, Option), - /// Conditionless loop (can be exited with break, continue, or return) - /// - /// `'label: loop { block }` - Loop(Block, Option), - /// A `match` block. - Match(Box, Vec), - /// A closure (for example, `move |a, b, c| {a + b + c}`) - Closure(CaptureBy, Box, Block), - /// A block (`{ ... }` or `unsafe { ... }`) - Block(BlockCheckMode, Block), - - /// An assignment (`a = foo()`) - Assign(Box, Box), - /// An assignment with an operator - /// - /// For example, `a += 1`. - AssignOp(BinOp, Box, Box), - /// Access of a named struct field (`obj.foo`) - Field(Box, Ident), - /// Access of an unnamed field of a struct or tuple-struct - /// - /// For example, `foo.0`. - TupField(Box, usize), - /// An indexing operation (`foo[2]`) - Index(Box, Box), - /// A range (`1..2`, `1..`, `..2`, `1...2`, `1...`, `...2`) - Range(Option>, Option>, RangeLimits), - - /// Variable reference, possibly containing `::` and/or type - /// parameters, e.g. foo::bar::. - /// - /// Optionally "qualified", - /// E.g. ` as SomeTrait>::SomeType`. - Path(Option, Path), - - /// A referencing operation (`&a` or `&mut a`) - AddrOf(Mutability, Box), - /// A `break`, with an optional label to break - Break(Option), - /// A `continue`, with an optional label - Continue(Option), - /// A `return`, with an optional value to be returned - Ret(Option>), - - /// A macro invocation; pre-expansion - Mac(Mac), - - /// A struct literal expression. - /// - /// For example, `Foo {x: 1, y: 2}`, or - /// `Foo {x: 1, .. base}`, where `base` is the `Option`. - Struct(Path, Vec, Option>), - - /// An array literal constructed from one repeated element. - /// - /// For example, `[1; 5]`. The first expression is the element - /// to be repeated; the second is the number of times to repeat it. - Repeat(Box, Box), - - /// No-op: used solely so we can pretty-print faithfully - Paren(Box), - - /// `expr?` - Try(Box), -} - -#[derive(Debug, Clone, Eq, PartialEq, Hash)] -pub struct FieldValue { - pub ident: Ident, - pub expr: Expr, - pub is_shorthand: bool, -} - -/// A Block (`{ .. }`). -/// -/// E.g. `{ .. }` as in `fn foo() { .. }` -#[derive(Debug, Clone, Eq, PartialEq, Hash)] -pub struct Block { - /// Statements in a block - pub stmts: Vec, -} - -#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] -pub enum BlockCheckMode { - Default, - Unsafe, -} - -#[derive(Debug, Clone, Eq, PartialEq, Hash)] -pub enum Stmt { - /// A local (let) binding. - Local(Box), - - /// An item definition. - Item(Box), - - /// Expr without trailing semi-colon. - Expr(Box), - - Semi(Box), - - Mac(Box<(Mac, MacStmtStyle, Vec)>), -} - -#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] -pub enum MacStmtStyle { - /// The macro statement had a trailing semicolon, e.g. `foo! { ... };` - /// `foo!(...);`, `foo![...];` - Semicolon, - /// The macro statement had braces; e.g. foo! { ... } - Braces, - /// The macro statement had parentheses or brackets and no semicolon; e.g. - /// `foo!(...)`. All of these will end up being converted into macro - /// expressions. - NoBraces, -} - -/// Local represents a `let` statement, e.g., `let : = ;` -#[derive(Debug, Clone, Eq, PartialEq, Hash)] -pub struct Local { - pub pat: Box, - pub ty: Option>, - /// Initializer expression to set the value, if any - pub init: Option>, - pub attrs: Vec, -} - -#[derive(Debug, Clone, Eq, PartialEq, Hash)] -// Clippy false positive -// https://github.com/Manishearth/rust-clippy/issues/1241 -#[cfg_attr(feature = "clippy", allow(enum_variant_names))] -pub enum Pat { - /// Represents a wildcard pattern (`_`) - Wild, - - /// A `Pat::Ident` may either be a new bound variable (`ref mut binding @ OPT_SUBPATTERN`), - /// or a unit struct/variant pattern, or a const pattern (in the last two cases the third - /// field must be `None`). Disambiguation cannot be done with parser alone, so it happens - /// during name resolution. - Ident(BindingMode, Ident, Option>), - - /// A struct or struct variant pattern, e.g. `Variant {x, y, ..}`. - /// The `bool` is `true` in the presence of a `..`. - Struct(Path, Vec, bool), - - /// A tuple struct/variant pattern `Variant(x, y, .., z)`. - /// If the `..` pattern fragment is present, then `Option` denotes its position. - /// 0 <= position <= subpats.len() - TupleStruct(Path, Vec, Option), - - /// A possibly qualified path pattern. - /// Unquailfied path patterns `A::B::C` can legally refer to variants, structs, constants - /// or associated constants. Quailfied path patterns `::B::C`/`::B::C` can - /// only legally refer to associated constants. - Path(Option, Path), - - /// A tuple pattern `(a, b)`. - /// If the `..` pattern fragment is present, then `Option` denotes its position. - /// 0 <= position <= subpats.len() - Tuple(Vec, Option), - /// A `box` pattern - Box(Box), - /// A reference pattern, e.g. `&mut (a, b)` - Ref(Box, Mutability), - /// A literal - Lit(Box), - /// A range pattern, e.g. `1...2` - Range(Box, Box), - /// `[a, b, ..i, y, z]` is represented as: - /// `Pat::Slice(box [a, b], Some(i), box [y, z])` - Slice(Vec, Option>, Vec), - /// A macro pattern; pre-expansion - Mac(Mac), -} - -/// An arm of a 'match'. -/// -/// E.g. `0...10 => { println!("match!") }` as in -/// -/// ```rust,ignore -/// match n { -/// 0...10 => { println!("match!") }, -/// // .. -/// } -/// ``` -#[derive(Debug, Clone, Eq, PartialEq, Hash)] -pub struct Arm { - pub attrs: Vec, - pub pats: Vec, - pub guard: Option>, - pub body: Box, -} - -/// A capture clause -#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] -pub enum CaptureBy { - Value, - Ref, -} - -/// Limit types of a range (inclusive or exclusive) -#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] -pub enum RangeLimits { - /// Inclusive at the beginning, exclusive at the end - HalfOpen, - /// Inclusive at the beginning and end - Closed, -} - -/// A single field in a struct pattern -/// -/// Patterns like the fields of Foo `{ x, ref y, ref mut z }` -/// are treated the same as `x: x, y: ref y, z: ref mut z`, -/// except `is_shorthand` is true -#[derive(Debug, Clone, Eq, PartialEq, Hash)] -pub struct FieldPat { - /// The identifier for the field - pub ident: Ident, - /// The pattern the field is destructured to - pub pat: Box, - pub is_shorthand: bool, -} - -#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] -pub enum BindingMode { - ByRef(Mutability), - ByValue(Mutability), -} - -#[cfg(feature = "parsing")] -pub mod parsing { - use super::*; - use {BinOp, Delimited, DelimToken, FnArg, FnDecl, FunctionRetTy, Ident, Lifetime, Mac, - TokenTree, Ty, UnOp}; - use attr::parsing::outer_attr; - use generics::parsing::lifetime; - use ident::parsing::{ident, wordlike}; - use item::parsing::item; - use lit::parsing::{digits, lit}; - use mac::parsing::{mac, token_trees}; - use nom::IResult::{self, Error}; - use op::parsing::{assign_op, binop, unop}; - use ty::parsing::{mutability, path, qpath, ty}; - - // Struct literals are ambiguous in certain positions - // https://github.com/rust-lang/rfcs/pull/92 - macro_rules! named_ambiguous_expr { - ($name:ident -> $o:ty, $allow_struct:ident, $submac:ident!( $($args:tt)* )) => { - fn $name(i: &str, $allow_struct: bool) -> $crate::nom::IResult<&str, $o> { - $submac!(i, $($args)*) - } - }; - } - - macro_rules! ambiguous_expr { - ($i:expr, $allow_struct:ident) => { - ambiguous_expr($i, $allow_struct, true) - }; - } - - named!(pub expr -> Expr, ambiguous_expr!(true)); - - named!(expr_no_struct -> Expr, ambiguous_expr!(false)); - - fn ambiguous_expr(i: &str, allow_struct: bool, allow_block: bool) -> IResult<&str, Expr> { - do_parse!( - i, - mut e: alt!( - expr_lit // must be before expr_struct - | - cond_reduce!(allow_struct, expr_struct) // must be before expr_path - | - expr_paren // must be before expr_tup - | - expr_mac // must be before expr_path - | - expr_break // must be before expr_path - | - expr_continue // must be before expr_path - | - call!(expr_ret, allow_struct) // must be before expr_path - | - call!(expr_box, allow_struct) - | - expr_in_place - | - expr_vec - | - expr_tup - | - call!(expr_unary, allow_struct) - | - expr_if - | - expr_while - | - expr_for_loop - | - expr_loop - | - expr_match - | - call!(expr_closure, allow_struct) - | - cond_reduce!(allow_block, expr_block) - | - call!(expr_range, allow_struct) - | - expr_path - | - call!(expr_addr_of, allow_struct) - | - expr_repeat - ) >> - many0!(alt!( - tap!(args: and_call => { - e = ExprKind::Call(Box::new(e.into()), args); - }) - | - tap!(more: and_method_call => { - let (method, ascript, mut args) = more; - args.insert(0, e.into()); - e = ExprKind::MethodCall(method, ascript, args); - }) - | - tap!(more: call!(and_binary, allow_struct) => { - let (op, other) = more; - e = ExprKind::Binary(op, Box::new(e.into()), Box::new(other)); - }) - | - tap!(ty: and_cast => { - e = ExprKind::Cast(Box::new(e.into()), Box::new(ty)); - }) - | - tap!(ty: and_ascription => { - e = ExprKind::Type(Box::new(e.into()), Box::new(ty)); - }) - | - tap!(v: call!(and_assign, allow_struct) => { - e = ExprKind::Assign(Box::new(e.into()), Box::new(v)); - }) - | - tap!(more: call!(and_assign_op, allow_struct) => { - let (op, v) = more; - e = ExprKind::AssignOp(op, Box::new(e.into()), Box::new(v)); - }) - | - tap!(field: and_field => { - e = ExprKind::Field(Box::new(e.into()), field); - }) - | - tap!(field: and_tup_field => { - e = ExprKind::TupField(Box::new(e.into()), field as usize); - }) - | - tap!(i: and_index => { - e = ExprKind::Index(Box::new(e.into()), Box::new(i)); - }) - | - tap!(more: call!(and_range, allow_struct) => { - let (limits, hi) = more; - e = ExprKind::Range(Some(Box::new(e.into())), hi.map(Box::new), limits); - }) - | - tap!(_try: punct!("?") => { - e = ExprKind::Try(Box::new(e.into())); - }) - )) >> - (e.into()) - ) - } - - named!(expr_mac -> ExprKind, map!(mac, ExprKind::Mac)); - - named!(expr_paren -> ExprKind, do_parse!( - punct!("(") >> - e: expr >> - punct!(")") >> - (ExprKind::Paren(Box::new(e))) - )); - - named_ambiguous_expr!(expr_box -> ExprKind, allow_struct, do_parse!( - keyword!("box") >> - inner: ambiguous_expr!(allow_struct) >> - (ExprKind::Box(Box::new(inner))) - )); - - named!(expr_in_place -> ExprKind, do_parse!( - keyword!("in") >> - place: expr_no_struct >> - punct!("{") >> - value: within_block >> - punct!("}") >> - (ExprKind::InPlace( - Box::new(place), - Box::new(ExprKind::Block(BlockCheckMode::Default, Block { - stmts: value, - }).into()), - )) - )); - - named!(expr_vec -> ExprKind, do_parse!( - punct!("[") >> - elems: terminated_list!(punct!(","), expr) >> - punct!("]") >> - (ExprKind::Vec(elems)) - )); - - named!(and_call -> Vec, do_parse!( - punct!("(") >> - args: terminated_list!(punct!(","), expr) >> - punct!(")") >> - (args) - )); - - named!(and_method_call -> (Ident, Vec, Vec), do_parse!( - punct!(".") >> - method: ident >> - ascript: opt_vec!(preceded!( - punct!("::"), - delimited!( - punct!("<"), - terminated_list!(punct!(","), ty), - punct!(">") - ) - )) >> - punct!("(") >> - args: terminated_list!(punct!(","), expr) >> - punct!(")") >> - (method, ascript, args) - )); - - named!(expr_tup -> ExprKind, do_parse!( - punct!("(") >> - elems: terminated_list!(punct!(","), expr) >> - punct!(")") >> - (ExprKind::Tup(elems)) - )); - - named_ambiguous_expr!(and_binary -> (BinOp, Expr), allow_struct, tuple!( - binop, - ambiguous_expr!(allow_struct) - )); - - named_ambiguous_expr!(expr_unary -> ExprKind, allow_struct, do_parse!( - operator: unop >> - operand: ambiguous_expr!(allow_struct) >> - (ExprKind::Unary(operator, Box::new(operand))) - )); - - named!(expr_lit -> ExprKind, map!(lit, ExprKind::Lit)); - - named!(and_cast -> Ty, do_parse!( - keyword!("as") >> - ty: ty >> - (ty) - )); - - named!(and_ascription -> Ty, preceded!(punct!(":"), ty)); - - enum Cond { - Let(Pat, Expr), - Expr(Expr), - } - - named!(cond -> Cond, alt!( - do_parse!( - keyword!("let") >> - pat: pat >> - punct!("=") >> - value: expr_no_struct >> - (Cond::Let(pat, value)) - ) - | - map!(expr_no_struct, Cond::Expr) - )); - - named!(expr_if -> ExprKind, do_parse!( - keyword!("if") >> - cond: cond >> - punct!("{") >> - then_block: within_block >> - punct!("}") >> - else_block: option!(preceded!( - keyword!("else"), - alt!( - expr_if - | - do_parse!( - punct!("{") >> - else_block: within_block >> - punct!("}") >> - (ExprKind::Block(BlockCheckMode::Default, Block { - stmts: else_block, - }).into()) - ) - ) - )) >> - (match cond { - Cond::Let(pat, expr) => ExprKind::IfLet( - Box::new(pat), - Box::new(expr), - Block { - stmts: then_block, - }, - else_block.map(|els| Box::new(els.into())), - ), - Cond::Expr(cond) => ExprKind::If( - Box::new(cond), - Block { - stmts: then_block, - }, - else_block.map(|els| Box::new(els.into())), - ), - }) - )); - - named!(expr_for_loop -> ExprKind, do_parse!( - lbl: option!(terminated!(label, punct!(":"))) >> - keyword!("for") >> - pat: pat >> - keyword!("in") >> - expr: expr_no_struct >> - loop_block: block >> - (ExprKind::ForLoop(Box::new(pat), Box::new(expr), loop_block, lbl)) - )); - - named!(expr_loop -> ExprKind, do_parse!( - lbl: option!(terminated!(label, punct!(":"))) >> - keyword!("loop") >> - loop_block: block >> - (ExprKind::Loop(loop_block, lbl)) - )); - - named!(expr_match -> ExprKind, do_parse!( - keyword!("match") >> - obj: expr_no_struct >> - punct!("{") >> - mut arms: many0!(do_parse!( - arm: match_arm >> - cond!(arm_requires_comma(&arm), punct!(",")) >> - cond!(!arm_requires_comma(&arm), option!(punct!(","))) >> - (arm) - )) >> - last_arm: option!(match_arm) >> - punct!("}") >> - (ExprKind::Match(Box::new(obj), { - arms.extend(last_arm); - arms - })) - )); - - fn arm_requires_comma(arm: &Arm) -> bool { - if let ExprKind::Block(BlockCheckMode::Default, _) = arm.body.node { - false - } else { - true - } - } - - named!(match_arm -> Arm, do_parse!( - attrs: many0!(outer_attr) >> - pats: separated_nonempty_list!(punct!("|"), pat) >> - guard: option!(preceded!(keyword!("if"), expr)) >> - punct!("=>") >> - body: alt!( - map!(block, |blk| ExprKind::Block(BlockCheckMode::Default, blk).into()) - | - expr - ) >> - (Arm { - attrs: attrs, - pats: pats, - guard: guard.map(Box::new), - body: Box::new(body), - }) - )); - - named_ambiguous_expr!(expr_closure -> ExprKind, allow_struct, do_parse!( - capture: capture_by >> - punct!("|") >> - inputs: terminated_list!(punct!(","), closure_arg) >> - punct!("|") >> - ret_and_body: alt!( - do_parse!( - punct!("->") >> - ty: ty >> - body: block >> - ((FunctionRetTy::Ty(ty), body)) - ) - | - map!(ambiguous_expr!(allow_struct), |e| ( - FunctionRetTy::Default, - Block { - stmts: vec![Stmt::Expr(Box::new(e))], - }, - )) - ) >> - (ExprKind::Closure( - capture, - Box::new(FnDecl { - inputs: inputs, - output: ret_and_body.0, - variadic: false, - }), - ret_and_body.1, - )) - )); - - named!(closure_arg -> FnArg, do_parse!( - pat: pat >> - ty: option!(preceded!(punct!(":"), ty)) >> - (FnArg::Captured(pat, ty.unwrap_or(Ty::Infer))) - )); - - named!(expr_while -> ExprKind, do_parse!( - lbl: option!(terminated!(label, punct!(":"))) >> - keyword!("while") >> - cond: cond >> - while_block: block >> - (match cond { - Cond::Let(pat, expr) => ExprKind::WhileLet( - Box::new(pat), - Box::new(expr), - while_block, - lbl, - ), - Cond::Expr(cond) => ExprKind::While( - Box::new(cond), - while_block, - lbl, - ), - }) - )); - - named!(expr_continue -> ExprKind, do_parse!( - keyword!("continue") >> - lbl: option!(label) >> - (ExprKind::Continue(lbl)) - )); - - named!(expr_break -> ExprKind, do_parse!( - keyword!("break") >> - lbl: option!(label) >> - (ExprKind::Break(lbl)) - )); - - named_ambiguous_expr!(expr_ret -> ExprKind, allow_struct, do_parse!( - keyword!("return") >> - ret_value: option!(ambiguous_expr!(allow_struct)) >> - (ExprKind::Ret(ret_value.map(Box::new))) - )); - - named!(expr_struct -> ExprKind, do_parse!( - path: path >> - punct!("{") >> - fields: separated_list!(punct!(","), field_value) >> - base: option!(do_parse!( - cond!(!fields.is_empty(), punct!(",")) >> - punct!("..") >> - base: expr >> - (base) - )) >> - cond!(!fields.is_empty() && base.is_none(), option!(punct!(","))) >> - punct!("}") >> - (ExprKind::Struct(path, fields, base.map(Box::new))) - )); - - named!(field_value -> FieldValue, alt!( - do_parse!( - name: wordlike >> - punct!(":") >> - value: expr >> - (FieldValue { - ident: name, - expr: value, - is_shorthand: false, - }) - ) - | - map!(ident, |name: Ident| FieldValue { - ident: name.clone(), - expr: ExprKind::Path(None, name.into()).into(), - is_shorthand: true, - }) - )); - - named!(expr_repeat -> ExprKind, do_parse!( - punct!("[") >> - value: expr >> - punct!(";") >> - times: expr >> - punct!("]") >> - (ExprKind::Repeat(Box::new(value), Box::new(times))) - )); - - named!(expr_block -> ExprKind, do_parse!( - rules: block_check_mode >> - b: block >> - (ExprKind::Block(rules, Block { - stmts: b.stmts, - })) - )); - - named_ambiguous_expr!(expr_range -> ExprKind, allow_struct, do_parse!( - limits: range_limits >> - hi: option!(ambiguous_expr!(allow_struct)) >> - (ExprKind::Range(None, hi.map(Box::new), limits)) - )); - - named!(range_limits -> RangeLimits, alt!( - punct!("...") => { |_| RangeLimits::Closed } - | - punct!("..") => { |_| RangeLimits::HalfOpen } - )); - - named!(expr_path -> ExprKind, map!(qpath, |(qself, path)| ExprKind::Path(qself, path))); - - named_ambiguous_expr!(expr_addr_of -> ExprKind, allow_struct, do_parse!( - punct!("&") >> - mutability: mutability >> - expr: ambiguous_expr!(allow_struct) >> - (ExprKind::AddrOf(mutability, Box::new(expr))) - )); - - named_ambiguous_expr!(and_assign -> Expr, allow_struct, preceded!( - punct!("="), - ambiguous_expr!(allow_struct) - )); - - named_ambiguous_expr!(and_assign_op -> (BinOp, Expr), allow_struct, tuple!( - assign_op, - ambiguous_expr!(allow_struct) - )); - - named!(and_field -> Ident, preceded!(punct!("."), ident)); - - named!(and_tup_field -> u64, preceded!(punct!("."), digits)); - - named!(and_index -> Expr, delimited!(punct!("["), expr, punct!("]"))); - - named_ambiguous_expr!(and_range -> (RangeLimits, Option), allow_struct, tuple!( - range_limits, - option!(call!(ambiguous_expr, allow_struct, false)) - )); - - named!(pub block -> Block, do_parse!( - punct!("{") >> - stmts: within_block >> - punct!("}") >> - (Block { - stmts: stmts, - }) - )); - - named!(block_check_mode -> BlockCheckMode, alt!( - keyword!("unsafe") => { |_| BlockCheckMode::Unsafe } - | - epsilon!() => { |_| BlockCheckMode::Default } - )); - - named!(pub within_block -> Vec, do_parse!( - many0!(punct!(";")) >> - mut standalone: many0!(terminated!(standalone_stmt, many0!(punct!(";")))) >> - last: option!(expr) >> - (match last { - None => standalone, - Some(last) => { - standalone.push(Stmt::Expr(Box::new(last))); - standalone - } - }) - )); - - named!(standalone_stmt -> Stmt, alt!( - stmt_mac - | - stmt_local - | - stmt_item - | - stmt_expr - )); - - named!(stmt_mac -> Stmt, do_parse!( - attrs: many0!(outer_attr) >> - name: ident >> - punct!("!") >> - // Only parse braces here; paren and bracket will get parsed as - // expression statements - punct!("{") >> - tts: token_trees >> - punct!("}") >> - semi: option!(punct!(";")) >> - (Stmt::Mac(Box::new(( - Mac { - path: name.into(), - tts: vec![TokenTree::Delimited(Delimited { - delim: DelimToken::Brace, - tts: tts, - })], - }, - if semi.is_some() { - MacStmtStyle::Semicolon - } else { - MacStmtStyle::Braces - }, - attrs, - )))) - )); - - named!(stmt_local -> Stmt, do_parse!( - attrs: many0!(outer_attr) >> - keyword!("let") >> - pat: pat >> - ty: option!(preceded!(punct!(":"), ty)) >> - init: option!(preceded!(punct!("="), expr)) >> - punct!(";") >> - (Stmt::Local(Box::new(Local { - pat: Box::new(pat), - ty: ty.map(Box::new), - init: init.map(Box::new), - attrs: attrs, - }))) - )); - - named!(stmt_item -> Stmt, map!(item, |i| Stmt::Item(Box::new(i)))); - - fn requires_semi(e: &Expr) -> bool { - match e.node { - ExprKind::If(_, _, _) | - ExprKind::IfLet(_, _, _, _) | - ExprKind::While(_, _, _) | - ExprKind::WhileLet(_, _, _, _) | - ExprKind::ForLoop(_, _, _, _) | - ExprKind::Loop(_, _) | - ExprKind::Match(_, _) | - ExprKind::Block(_, _) => false, - - _ => true, - } - } - - named!(stmt_expr -> Stmt, do_parse!( - attrs: many0!(outer_attr) >> - mut e: expr >> - semi: option!(punct!(";")) >> - ({ - e.attrs = attrs; - if semi.is_some() { - Stmt::Semi(Box::new(e)) - } else if requires_semi(&e) { - return Error; - } else { - Stmt::Expr(Box::new(e)) - } - }) - )); - - named!(pub pat -> Pat, alt!( - pat_wild // must be before pat_ident - | - pat_box // must be before pat_ident - | - pat_range // must be before pat_lit - | - pat_tuple_struct // must be before pat_ident - | - pat_struct // must be before pat_ident - | - pat_mac // must be before pat_ident - | - pat_lit // must be before pat_ident - | - pat_ident // must be before pat_path - | - pat_path - | - pat_tuple - | - pat_ref - | - pat_slice - )); - - named!(pat_mac -> Pat, map!(mac, Pat::Mac)); - - named!(pat_wild -> Pat, map!(keyword!("_"), |_| Pat::Wild)); - - named!(pat_box -> Pat, do_parse!( - keyword!("box") >> - pat: pat >> - (Pat::Box(Box::new(pat))) - )); - - named!(pat_ident -> Pat, do_parse!( - mode: option!(keyword!("ref")) >> - mutability: mutability >> - name: alt!( - ident - | - keyword!("self") => { Into::into } - ) >> - not!(peek!(punct!("<"))) >> - not!(peek!(punct!("::"))) >> - subpat: option!(preceded!(punct!("@"), pat)) >> - (Pat::Ident( - if mode.is_some() { - BindingMode::ByRef(mutability) - } else { - BindingMode::ByValue(mutability) - }, - name, - subpat.map(Box::new), - )) - )); - - named!(pat_tuple_struct -> Pat, do_parse!( - path: path >> - tuple: pat_tuple_helper >> - (Pat::TupleStruct(path, tuple.0, tuple.1)) - )); - - named!(pat_struct -> Pat, do_parse!( - path: path >> - punct!("{") >> - fields: separated_list!(punct!(","), field_pat) >> - more: option!(preceded!( - cond!(!fields.is_empty(), punct!(",")), - punct!("..") - )) >> - cond!(!fields.is_empty() && more.is_none(), option!(punct!(","))) >> - punct!("}") >> - (Pat::Struct(path, fields, more.is_some())) - )); - - named!(field_pat -> FieldPat, alt!( - do_parse!( - ident: wordlike >> - punct!(":") >> - pat: pat >> - (FieldPat { - ident: ident, - pat: Box::new(pat), - is_shorthand: false, - }) - ) - | - do_parse!( - boxed: option!(keyword!("box")) >> - mode: option!(keyword!("ref")) >> - mutability: mutability >> - ident: ident >> - ({ - let mut pat = Pat::Ident( - if mode.is_some() { - BindingMode::ByRef(mutability) - } else { - BindingMode::ByValue(mutability) - }, - ident.clone(), - None, - ); - if boxed.is_some() { - pat = Pat::Box(Box::new(pat)); - } - FieldPat { - ident: ident, - pat: Box::new(pat), - is_shorthand: true, - } - }) - ) - )); - - named!(pat_path -> Pat, map!(qpath, |(qself, path)| Pat::Path(qself, path))); - - named!(pat_tuple -> Pat, map!( - pat_tuple_helper, - |(pats, dotdot)| Pat::Tuple(pats, dotdot) - )); - - named!(pat_tuple_helper -> (Vec, Option), do_parse!( - punct!("(") >> - mut elems: separated_list!(punct!(","), pat) >> - dotdot: option!(do_parse!( - cond!(!elems.is_empty(), punct!(",")) >> - punct!("..") >> - rest: many0!(preceded!(punct!(","), pat)) >> - cond!(!rest.is_empty(), option!(punct!(","))) >> - (rest) - )) >> - cond!(!elems.is_empty() && dotdot.is_none(), option!(punct!(","))) >> - punct!(")") >> - (match dotdot { - Some(rest) => { - let pos = elems.len(); - elems.extend(rest); - (elems, Some(pos)) - } - None => (elems, None), - }) - )); - - named!(pat_ref -> Pat, do_parse!( - punct!("&") >> - mutability: mutability >> - pat: pat >> - (Pat::Ref(Box::new(pat), mutability)) - )); - - named!(pat_lit -> Pat, do_parse!( - lit: pat_lit_expr >> - (if let ExprKind::Path(_, _) = lit.node { - return IResult::Error; // these need to be parsed by pat_path - } else { - Pat::Lit(Box::new(lit)) - }) - )); - - named!(pat_range -> Pat, do_parse!( - lo: pat_lit_expr >> - punct!("...") >> - hi: pat_lit_expr >> - (Pat::Range(Box::new(lo), Box::new(hi))) - )); - - named!(pat_lit_expr -> Expr, do_parse!( - neg: option!(punct!("-")) >> - v: alt!( - lit => { ExprKind::Lit } - | - path => { |p| ExprKind::Path(None, p) } - ) >> - (if neg.is_some() { - ExprKind::Unary(UnOp::Neg, Box::new(v.into())).into() - } else { - v.into() - }) - )); - - named!(pat_slice -> Pat, do_parse!( - punct!("[") >> - mut before: separated_list!(punct!(","), pat) >> - after: option!(do_parse!( - comma_before_dots: option!(cond_reduce!(!before.is_empty(), punct!(","))) >> - punct!("..") >> - after: many0!(preceded!(punct!(","), pat)) >> - cond!(!after.is_empty(), option!(punct!(","))) >> - (comma_before_dots.is_some(), after) - )) >> - cond!(after.is_none(), option!(punct!(","))) >> - punct!("]") >> - (match after { - None => Pat::Slice(before, None, Vec::new()), - Some((true, after)) => { - if before.is_empty() { - return IResult::Error; - } - Pat::Slice(before, Some(Box::new(Pat::Wild)), after) - } - Some((false, after)) => { - let rest = before.pop().unwrap_or(Pat::Wild); - Pat::Slice(before, Some(Box::new(rest)), after) - } - }) - )); - - named!(capture_by -> CaptureBy, alt!( - keyword!("move") => { |_| CaptureBy::Value } - | - epsilon!() => { |_| CaptureBy::Ref } - )); - - named!(label -> Ident, map!(lifetime, |lt: Lifetime| lt.ident)); -} - -#[cfg(feature = "printing")] -mod printing { - use super::*; - use {FnArg, FunctionRetTy, Mutability, Ty}; - use attr::FilterAttrs; - use quote::{Tokens, ToTokens}; - - impl ToTokens for Expr { - fn to_tokens(&self, tokens: &mut Tokens) { - tokens.append_all(self.attrs.outer()); - match self.node { - ExprKind::Box(ref inner) => { - tokens.append("box"); - inner.to_tokens(tokens); - } - ExprKind::InPlace(ref place, ref value) => { - tokens.append("in"); - place.to_tokens(tokens); - value.to_tokens(tokens); - } - ExprKind::Vec(ref tys) => { - tokens.append("["); - tokens.append_separated(tys, ","); - tokens.append("]"); - } - ExprKind::Call(ref func, ref args) => { - func.to_tokens(tokens); - tokens.append("("); - tokens.append_separated(args, ","); - tokens.append(")"); - } - ExprKind::MethodCall(ref ident, ref ascript, ref args) => { - args[0].to_tokens(tokens); - tokens.append("."); - ident.to_tokens(tokens); - if !ascript.is_empty() { - tokens.append("::"); - tokens.append("<"); - tokens.append_separated(ascript, ","); - tokens.append(">"); - } - tokens.append("("); - tokens.append_separated(&args[1..], ","); - tokens.append(")"); - } - ExprKind::Tup(ref fields) => { - tokens.append("("); - tokens.append_separated(fields, ","); - if fields.len() == 1 { - tokens.append(","); - } - tokens.append(")"); - } - ExprKind::Binary(op, ref left, ref right) => { - left.to_tokens(tokens); - op.to_tokens(tokens); - right.to_tokens(tokens); - } - ExprKind::Unary(op, ref expr) => { - op.to_tokens(tokens); - expr.to_tokens(tokens); - } - ExprKind::Lit(ref lit) => lit.to_tokens(tokens), - ExprKind::Cast(ref expr, ref ty) => { - expr.to_tokens(tokens); - tokens.append("as"); - ty.to_tokens(tokens); - } - ExprKind::Type(ref expr, ref ty) => { - expr.to_tokens(tokens); - tokens.append(":"); - ty.to_tokens(tokens); - } - ExprKind::If(ref cond, ref then_block, ref else_block) => { - tokens.append("if"); - cond.to_tokens(tokens); - then_block.to_tokens(tokens); - if let Some(ref else_block) = *else_block { - tokens.append("else"); - else_block.to_tokens(tokens); - } - } - ExprKind::IfLet(ref pat, ref expr, ref then_block, ref else_block) => { - tokens.append("if"); - tokens.append("let"); - pat.to_tokens(tokens); - tokens.append("="); - expr.to_tokens(tokens); - then_block.to_tokens(tokens); - if let Some(ref else_block) = *else_block { - tokens.append("else"); - else_block.to_tokens(tokens); - } - } - ExprKind::While(ref cond, ref body, ref label) => { - if let Some(ref label) = *label { - label.to_tokens(tokens); - tokens.append(":"); - } - tokens.append("while"); - cond.to_tokens(tokens); - body.to_tokens(tokens); - } - ExprKind::WhileLet(ref pat, ref expr, ref body, ref label) => { - if let Some(ref label) = *label { - label.to_tokens(tokens); - tokens.append(":"); - } - tokens.append("while"); - tokens.append("let"); - pat.to_tokens(tokens); - tokens.append("="); - expr.to_tokens(tokens); - body.to_tokens(tokens); - } - ExprKind::ForLoop(ref pat, ref expr, ref body, ref label) => { - if let Some(ref label) = *label { - label.to_tokens(tokens); - tokens.append(":"); - } - tokens.append("for"); - pat.to_tokens(tokens); - tokens.append("in"); - expr.to_tokens(tokens); - body.to_tokens(tokens); - } - ExprKind::Loop(ref body, ref label) => { - if let Some(ref label) = *label { - label.to_tokens(tokens); - tokens.append(":"); - } - tokens.append("loop"); - body.to_tokens(tokens); - } - ExprKind::Match(ref expr, ref arms) => { - tokens.append("match"); - expr.to_tokens(tokens); - tokens.append("{"); - tokens.append_all(arms); - tokens.append("}"); - } - ExprKind::Closure(capture, ref decl, ref body) => { - capture.to_tokens(tokens); - tokens.append("|"); - for (i, input) in decl.inputs.iter().enumerate() { - if i > 0 { - tokens.append(","); - } - match *input { - FnArg::Captured(ref pat, Ty::Infer) => { - pat.to_tokens(tokens); - } - _ => input.to_tokens(tokens), - } - } - tokens.append("|"); - match decl.output { - FunctionRetTy::Default => { - if body.stmts.len() == 1 { - if let Stmt::Expr(ref expr) = body.stmts[0] { - expr.to_tokens(tokens); - } else { - body.to_tokens(tokens); - } - } else { - body.to_tokens(tokens); - } - } - FunctionRetTy::Ty(ref ty) => { - tokens.append("->"); - ty.to_tokens(tokens); - body.to_tokens(tokens); - } - } - } - ExprKind::Block(rules, ref block) => { - rules.to_tokens(tokens); - block.to_tokens(tokens); - } - ExprKind::Assign(ref var, ref expr) => { - var.to_tokens(tokens); - tokens.append("="); - expr.to_tokens(tokens); - } - ExprKind::AssignOp(op, ref var, ref expr) => { - var.to_tokens(tokens); - tokens.append(op.assign_op().unwrap()); - expr.to_tokens(tokens); - } - ExprKind::Field(ref expr, ref field) => { - expr.to_tokens(tokens); - tokens.append("."); - field.to_tokens(tokens); - } - ExprKind::TupField(ref expr, field) => { - expr.to_tokens(tokens); - tokens.append("."); - tokens.append(&field.to_string()); - } - ExprKind::Index(ref expr, ref index) => { - expr.to_tokens(tokens); - tokens.append("["); - index.to_tokens(tokens); - tokens.append("]"); - } - ExprKind::Range(ref from, ref to, limits) => { - from.to_tokens(tokens); - match limits { - RangeLimits::HalfOpen => tokens.append(".."), - RangeLimits::Closed => tokens.append("..."), - } - to.to_tokens(tokens); - } - ExprKind::Path(None, ref path) => path.to_tokens(tokens), - ExprKind::Path(Some(ref qself), ref path) => { - tokens.append("<"); - qself.ty.to_tokens(tokens); - if qself.position > 0 { - tokens.append("as"); - for (i, segment) in path.segments - .iter() - .take(qself.position) - .enumerate() { - if i > 0 || path.global { - tokens.append("::"); - } - segment.to_tokens(tokens); - } - } - tokens.append(">"); - for segment in path.segments.iter().skip(qself.position) { - tokens.append("::"); - segment.to_tokens(tokens); - } - } - ExprKind::AddrOf(mutability, ref expr) => { - tokens.append("&"); - mutability.to_tokens(tokens); - expr.to_tokens(tokens); - } - ExprKind::Break(ref opt_label) => { - tokens.append("break"); - opt_label.to_tokens(tokens); - } - ExprKind::Continue(ref opt_label) => { - tokens.append("continue"); - opt_label.to_tokens(tokens); - } - ExprKind::Ret(ref opt_expr) => { - tokens.append("return"); - opt_expr.to_tokens(tokens); - } - ExprKind::Mac(ref mac) => mac.to_tokens(tokens), - ExprKind::Struct(ref path, ref fields, ref base) => { - path.to_tokens(tokens); - tokens.append("{"); - tokens.append_separated(fields, ","); - if let Some(ref base) = *base { - if !fields.is_empty() { - tokens.append(","); - } - tokens.append(".."); - base.to_tokens(tokens); - } - tokens.append("}"); - } - ExprKind::Repeat(ref expr, ref times) => { - tokens.append("["); - expr.to_tokens(tokens); - tokens.append(";"); - times.to_tokens(tokens); - tokens.append("]"); - } - ExprKind::Paren(ref expr) => { - tokens.append("("); - expr.to_tokens(tokens); - tokens.append(")"); - } - ExprKind::Try(ref expr) => { - expr.to_tokens(tokens); - tokens.append("?"); - } - } - } - } - - impl ToTokens for FieldValue { - fn to_tokens(&self, tokens: &mut Tokens) { - self.ident.to_tokens(tokens); - if !self.is_shorthand { - tokens.append(":"); - self.expr.to_tokens(tokens); - } - } - } - - impl ToTokens for Arm { - fn to_tokens(&self, tokens: &mut Tokens) { - for attr in &self.attrs { - attr.to_tokens(tokens); - } - tokens.append_separated(&self.pats, "|"); - if let Some(ref guard) = self.guard { - tokens.append("if"); - guard.to_tokens(tokens); - } - tokens.append("=>"); - self.body.to_tokens(tokens); - match self.body.node { - ExprKind::Block(BlockCheckMode::Default, _) => { - // no comma - } - _ => tokens.append(","), - } - } - } - - impl ToTokens for Pat { - fn to_tokens(&self, tokens: &mut Tokens) { - match *self { - Pat::Wild => tokens.append("_"), - Pat::Ident(mode, ref ident, ref subpat) => { - mode.to_tokens(tokens); - ident.to_tokens(tokens); - if let Some(ref subpat) = *subpat { - tokens.append("@"); - subpat.to_tokens(tokens); - } - } - Pat::Struct(ref path, ref fields, dots) => { - path.to_tokens(tokens); - tokens.append("{"); - tokens.append_separated(fields, ","); - if dots { - if !fields.is_empty() { - tokens.append(","); - } - tokens.append(".."); - } - tokens.append("}"); - } - Pat::TupleStruct(ref path, ref pats, dotpos) => { - path.to_tokens(tokens); - tokens.append("("); - match dotpos { - Some(pos) => { - if pos > 0 { - tokens.append_separated(&pats[..pos], ","); - tokens.append(","); - } - tokens.append(".."); - if pos < pats.len() { - tokens.append(","); - tokens.append_separated(&pats[pos..], ","); - } - } - None => tokens.append_separated(pats, ","), - } - tokens.append(")"); - } - Pat::Path(None, ref path) => path.to_tokens(tokens), - Pat::Path(Some(ref qself), ref path) => { - tokens.append("<"); - qself.ty.to_tokens(tokens); - if qself.position > 0 { - tokens.append("as"); - for (i, segment) in path.segments - .iter() - .take(qself.position) - .enumerate() { - if i > 0 || path.global { - tokens.append("::"); - } - segment.to_tokens(tokens); - } - } - tokens.append(">"); - for segment in path.segments.iter().skip(qself.position) { - tokens.append("::"); - segment.to_tokens(tokens); - } - } - Pat::Tuple(ref pats, dotpos) => { - tokens.append("("); - match dotpos { - Some(pos) => { - if pos > 0 { - tokens.append_separated(&pats[..pos], ","); - tokens.append(","); - } - tokens.append(".."); - if pos < pats.len() { - tokens.append(","); - tokens.append_separated(&pats[pos..], ","); - } - } - None => { - tokens.append_separated(pats, ","); - if pats.len() == 1 { - tokens.append(","); - } - } - } - tokens.append(")"); - } - Pat::Box(ref inner) => { - tokens.append("box"); - inner.to_tokens(tokens); - } - Pat::Ref(ref target, mutability) => { - tokens.append("&"); - mutability.to_tokens(tokens); - target.to_tokens(tokens); - } - Pat::Lit(ref lit) => lit.to_tokens(tokens), - Pat::Range(ref lo, ref hi) => { - lo.to_tokens(tokens); - tokens.append("..."); - hi.to_tokens(tokens); - } - Pat::Slice(ref before, ref rest, ref after) => { - tokens.append("["); - tokens.append_separated(before, ","); - if let Some(ref rest) = *rest { - if !before.is_empty() { - tokens.append(","); - } - if **rest != Pat::Wild { - rest.to_tokens(tokens); - } - tokens.append(".."); - if !after.is_empty() { - tokens.append(","); - } - tokens.append_separated(after, ","); - } - tokens.append("]"); - } - Pat::Mac(ref mac) => mac.to_tokens(tokens), - } - } - } - - impl ToTokens for FieldPat { - fn to_tokens(&self, tokens: &mut Tokens) { - if !self.is_shorthand { - self.ident.to_tokens(tokens); - tokens.append(":"); - } - self.pat.to_tokens(tokens); - } - } - - impl ToTokens for BindingMode { - fn to_tokens(&self, tokens: &mut Tokens) { - match *self { - BindingMode::ByRef(Mutability::Immutable) => { - tokens.append("ref"); - } - BindingMode::ByRef(Mutability::Mutable) => { - tokens.append("ref"); - tokens.append("mut"); - } - BindingMode::ByValue(Mutability::Immutable) => {} - BindingMode::ByValue(Mutability::Mutable) => { - tokens.append("mut"); - } - } - } - } - - impl ToTokens for CaptureBy { - fn to_tokens(&self, tokens: &mut Tokens) { - match *self { - CaptureBy::Value => tokens.append("move"), - CaptureBy::Ref => { - // nothing - } - } - } - } - - impl ToTokens for Block { - fn to_tokens(&self, tokens: &mut Tokens) { - tokens.append("{"); - tokens.append_all(&self.stmts); - tokens.append("}"); - } - } - - impl ToTokens for BlockCheckMode { - fn to_tokens(&self, tokens: &mut Tokens) { - match *self { - BlockCheckMode::Default => { - // nothing - } - BlockCheckMode::Unsafe => tokens.append("unsafe"), - } - } - } - - impl ToTokens for Stmt { - fn to_tokens(&self, tokens: &mut Tokens) { - match *self { - Stmt::Local(ref local) => local.to_tokens(tokens), - Stmt::Item(ref item) => item.to_tokens(tokens), - Stmt::Expr(ref expr) => expr.to_tokens(tokens), - Stmt::Semi(ref expr) => { - expr.to_tokens(tokens); - tokens.append(";"); - } - Stmt::Mac(ref mac) => { - let (ref mac, style, ref attrs) = **mac; - tokens.append_all(attrs.outer()); - mac.to_tokens(tokens); - match style { - MacStmtStyle::Semicolon => tokens.append(";"), - MacStmtStyle::Braces | MacStmtStyle::NoBraces => { - // no semicolon - } - } - } - } - } - } - - impl ToTokens for Local { - fn to_tokens(&self, tokens: &mut Tokens) { - tokens.append_all(self.attrs.outer()); - tokens.append("let"); - self.pat.to_tokens(tokens); - if let Some(ref ty) = self.ty { - tokens.append(":"); - ty.to_tokens(tokens); - } - if let Some(ref init) = self.init { - tokens.append("="); - init.to_tokens(tokens); - } - tokens.append(";"); - } - } -} diff --git a/third_party/rust/syn-0.10.8/src/generics.rs b/third_party/rust/syn-0.10.8/src/generics.rs deleted file mode 100644 index d76051f4089b..000000000000 --- a/third_party/rust/syn-0.10.8/src/generics.rs +++ /dev/null @@ -1,446 +0,0 @@ -use super::*; - -/// Represents lifetimes and type parameters attached to a declaration -/// of a function, enum, trait, etc. -#[derive(Debug, Clone, Eq, PartialEq, Default, Hash)] -pub struct Generics { - pub lifetimes: Vec, - pub ty_params: Vec, - pub where_clause: WhereClause, -} - -#[cfg(feature = "printing")] -/// Returned by `Generics::split_for_impl`. -#[derive(Debug)] -pub struct ImplGenerics<'a>(&'a Generics); - -#[cfg(feature = "printing")] -/// Returned by `Generics::split_for_impl`. -#[derive(Debug)] -pub struct TyGenerics<'a>(&'a Generics); - -impl Generics { - #[cfg(feature = "printing")] - /// Split a type's generics into the pieces required for impl'ing a trait - /// for that type. - /// - /// ``` - /// # extern crate syn; - /// # #[macro_use] - /// # extern crate quote; - /// # fn main() { - /// # let generics: syn::Generics = Default::default(); - /// # let name = syn::Ident::new("MyType"); - /// let (impl_generics, ty_generics, where_clause) = generics.split_for_impl(); - /// quote! { - /// impl #impl_generics MyTrait for #name #ty_generics #where_clause { - /// // ... - /// } - /// } - /// # ; - /// # } - /// ``` - pub fn split_for_impl(&self) -> (ImplGenerics, TyGenerics, &WhereClause) { - (ImplGenerics(self), TyGenerics(self), &self.where_clause) - } -} - -#[derive(Debug, Clone, Eq, PartialEq, Hash)] -pub struct Lifetime { - pub ident: Ident, -} - -impl Lifetime { - pub fn new>(t: T) -> Self { - let id = Ident::new(t); - if !id.as_ref().starts_with('\'') { - panic!("lifetime name must start with apostrophe as in \"'a\", \ - got {:?}", - id.as_ref()); - } - Lifetime { ident: id } - } -} - -/// A lifetime definition, e.g. `'a: 'b+'c+'d` -#[derive(Debug, Clone, Eq, PartialEq, Hash)] -pub struct LifetimeDef { - pub attrs: Vec, - pub lifetime: Lifetime, - pub bounds: Vec, -} - -impl LifetimeDef { - pub fn new>(t: T) -> Self { - LifetimeDef { - attrs: Vec::new(), - lifetime: Lifetime::new(t), - bounds: Vec::new(), - } - } -} - -#[derive(Debug, Clone, Eq, PartialEq, Hash)] -pub struct TyParam { - pub attrs: Vec, - pub ident: Ident, - pub bounds: Vec, - pub default: Option, -} - -/// The AST represents all type param bounds as types. -/// `typeck::collect::compute_bounds` matches these against -/// the "special" built-in traits (see `middle::lang_items`) and -/// detects Copy, Send and Sync. -#[derive(Debug, Clone, Eq, PartialEq, Hash)] -pub enum TyParamBound { - Trait(PolyTraitRef, TraitBoundModifier), - Region(Lifetime), -} - -/// A modifier on a bound, currently this is only used for `?Sized`, where the -/// modifier is `Maybe`. Negative bounds should also be handled here. -#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] -pub enum TraitBoundModifier { - None, - Maybe, -} - -/// A `where` clause in a definition -#[derive(Debug, Clone, Eq, PartialEq, Default, Hash)] -pub struct WhereClause { - pub predicates: Vec, -} - -impl WhereClause { - pub fn none() -> Self { - WhereClause { predicates: Vec::new() } - } -} - -/// A single predicate in a `where` clause -#[derive(Debug, Clone, Eq, PartialEq, Hash)] -pub enum WherePredicate { - /// A type binding, e.g. `for<'c> Foo: Send+Clone+'c` - BoundPredicate(WhereBoundPredicate), - /// A lifetime predicate, e.g. `'a: 'b+'c` - RegionPredicate(WhereRegionPredicate), -} - -/// A type bound. -/// -/// E.g. `for<'c> Foo: Send+Clone+'c` -#[derive(Debug, Clone, Eq, PartialEq, Hash)] -pub struct WhereBoundPredicate { - /// Any lifetimes from a `for` binding - pub bound_lifetimes: Vec, - /// The type being bounded - pub bounded_ty: Ty, - /// Trait and lifetime bounds (`Clone+Send+'static`) - pub bounds: Vec, -} - -/// A lifetime predicate. -/// -/// E.g. `'a: 'b+'c` -#[derive(Debug, Clone, Eq, PartialEq, Hash)] -pub struct WhereRegionPredicate { - pub lifetime: Lifetime, - pub bounds: Vec, -} - -#[cfg(feature = "parsing")] -pub mod parsing { - use super::*; - use attr::parsing::outer_attr; - use ident::parsing::ident; - use ty::parsing::{ty, poly_trait_ref}; - - named!(pub generics -> Generics, map!( - alt!( - do_parse!( - punct!("<") >> - lifetimes: separated_list!(punct!(","), lifetime_def) >> - ty_params: opt_vec!(preceded!( - cond!(!lifetimes.is_empty(), punct!(",")), - separated_nonempty_list!(punct!(","), ty_param) - )) >> - cond!(!lifetimes.is_empty() || !ty_params.is_empty(), option!(punct!(","))) >> - punct!(">") >> - (lifetimes, ty_params) - ) - | - epsilon!() => { |_| (Vec::new(), Vec::new()) } - ), - |(lifetimes, ty_params)| Generics { - lifetimes: lifetimes, - ty_params: ty_params, - where_clause: Default::default(), - } - )); - - named!(pub lifetime -> Lifetime, preceded!( - punct!("'"), - alt!( - map!(ident, |id| Lifetime { - ident: format!("'{}", id).into(), - }) - | - map!(keyword!("static"), |_| Lifetime { - ident: "'static".into(), - }) - ) - )); - - named!(pub lifetime_def -> LifetimeDef, do_parse!( - attrs: many0!(outer_attr) >> - life: lifetime >> - bounds: opt_vec!(preceded!( - punct!(":"), - separated_list!(punct!("+"), lifetime) - )) >> - (LifetimeDef { - attrs: attrs, - lifetime: life, - bounds: bounds, - }) - )); - - named!(pub bound_lifetimes -> Vec, opt_vec!(do_parse!( - keyword!("for") >> - punct!("<") >> - lifetimes: terminated_list!(punct!(","), lifetime_def) >> - punct!(">") >> - (lifetimes) - ))); - - named!(ty_param -> TyParam, do_parse!( - attrs: many0!(outer_attr) >> - id: ident >> - bounds: opt_vec!(preceded!( - punct!(":"), - separated_nonempty_list!(punct!("+"), ty_param_bound) - )) >> - default: option!(preceded!( - punct!("="), - ty - )) >> - (TyParam { - attrs: attrs, - ident: id, - bounds: bounds, - default: default, - }) - )); - - named!(pub ty_param_bound -> TyParamBound, alt!( - preceded!(punct!("?"), poly_trait_ref) => { - |poly| TyParamBound::Trait(poly, TraitBoundModifier::Maybe) - } - | - lifetime => { TyParamBound::Region } - | - poly_trait_ref => { - |poly| TyParamBound::Trait(poly, TraitBoundModifier::None) - } - )); - - named!(pub where_clause -> WhereClause, alt!( - do_parse!( - keyword!("where") >> - predicates: separated_nonempty_list!(punct!(","), where_predicate) >> - option!(punct!(",")) >> - (WhereClause { predicates: predicates }) - ) - | - epsilon!() => { |_| Default::default() } - )); - - named!(where_predicate -> WherePredicate, alt!( - do_parse!( - ident: lifetime >> - bounds: opt_vec!(preceded!( - punct!(":"), - separated_list!(punct!("+"), lifetime) - )) >> - (WherePredicate::RegionPredicate(WhereRegionPredicate { - lifetime: ident, - bounds: bounds, - })) - ) - | - do_parse!( - bound_lifetimes: bound_lifetimes >> - bounded_ty: ty >> - punct!(":") >> - bounds: separated_nonempty_list!(punct!("+"), ty_param_bound) >> - (WherePredicate::BoundPredicate(WhereBoundPredicate { - bound_lifetimes: bound_lifetimes, - bounded_ty: bounded_ty, - bounds: bounds, - })) - ) - )); -} - -#[cfg(feature = "printing")] -mod printing { - use super::*; - use attr::FilterAttrs; - use quote::{Tokens, ToTokens}; - - impl ToTokens for Generics { - fn to_tokens(&self, tokens: &mut Tokens) { - let has_lifetimes = !self.lifetimes.is_empty(); - let has_ty_params = !self.ty_params.is_empty(); - if has_lifetimes || has_ty_params { - tokens.append("<"); - tokens.append_separated(&self.lifetimes, ","); - if has_lifetimes && has_ty_params { - tokens.append(","); - } - tokens.append_separated(&self.ty_params, ","); - tokens.append(">"); - } - } - } - - impl<'a> ToTokens for ImplGenerics<'a> { - fn to_tokens(&self, tokens: &mut Tokens) { - let has_lifetimes = !self.0.lifetimes.is_empty(); - let has_ty_params = !self.0.ty_params.is_empty(); - if has_lifetimes || has_ty_params { - tokens.append("<"); - tokens.append_separated(&self.0.lifetimes, ","); - // Leave off the type parameter defaults - for (i, ty_param) in self.0.ty_params.iter().enumerate() { - if i > 0 || has_lifetimes { - tokens.append(","); - } - tokens.append_all(ty_param.attrs.outer()); - ty_param.ident.to_tokens(tokens); - if !ty_param.bounds.is_empty() { - tokens.append(":"); - tokens.append_separated(&ty_param.bounds, "+"); - } - } - tokens.append(">"); - } - } - } - - impl<'a> ToTokens for TyGenerics<'a> { - fn to_tokens(&self, tokens: &mut Tokens) { - let has_lifetimes = !self.0.lifetimes.is_empty(); - let has_ty_params = !self.0.ty_params.is_empty(); - if has_lifetimes || has_ty_params { - tokens.append("<"); - // Leave off the lifetime bounds and attributes - let lifetimes = self.0.lifetimes.iter().map(|ld| &ld.lifetime); - tokens.append_separated(lifetimes, ","); - if has_lifetimes && has_ty_params { - tokens.append(","); - } - // Leave off the type parameter bounds, defaults, and attributes - let ty_params = self.0.ty_params.iter().map(|tp| &tp.ident); - tokens.append_separated(ty_params, ","); - tokens.append(">"); - } - } - } - - impl ToTokens for Lifetime { - fn to_tokens(&self, tokens: &mut Tokens) { - self.ident.to_tokens(tokens); - } - } - - impl ToTokens for LifetimeDef { - fn to_tokens(&self, tokens: &mut Tokens) { - tokens.append_all(self.attrs.outer()); - self.lifetime.to_tokens(tokens); - if !self.bounds.is_empty() { - tokens.append(":"); - tokens.append_separated(&self.bounds, "+"); - } - } - } - - impl ToTokens for TyParam { - fn to_tokens(&self, tokens: &mut Tokens) { - tokens.append_all(self.attrs.outer()); - self.ident.to_tokens(tokens); - if !self.bounds.is_empty() { - tokens.append(":"); - tokens.append_separated(&self.bounds, "+"); - } - if let Some(ref default) = self.default { - tokens.append("="); - default.to_tokens(tokens); - } - } - } - - impl ToTokens for TyParamBound { - fn to_tokens(&self, tokens: &mut Tokens) { - match *self { - TyParamBound::Region(ref lifetime) => lifetime.to_tokens(tokens), - TyParamBound::Trait(ref trait_ref, modifier) => { - match modifier { - TraitBoundModifier::None => {} - TraitBoundModifier::Maybe => tokens.append("?"), - } - trait_ref.to_tokens(tokens); - } - } - } - } - - impl ToTokens for WhereClause { - fn to_tokens(&self, tokens: &mut Tokens) { - if !self.predicates.is_empty() { - tokens.append("where"); - tokens.append_separated(&self.predicates, ","); - } - } - } - - impl ToTokens for WherePredicate { - fn to_tokens(&self, tokens: &mut Tokens) { - match *self { - WherePredicate::BoundPredicate(ref predicate) => { - predicate.to_tokens(tokens); - } - WherePredicate::RegionPredicate(ref predicate) => { - predicate.to_tokens(tokens); - } - } - } - } - - impl ToTokens for WhereBoundPredicate { - fn to_tokens(&self, tokens: &mut Tokens) { - if !self.bound_lifetimes.is_empty() { - tokens.append("for"); - tokens.append("<"); - tokens.append_separated(&self.bound_lifetimes, ","); - tokens.append(">"); - } - self.bounded_ty.to_tokens(tokens); - if !self.bounds.is_empty() { - tokens.append(":"); - tokens.append_separated(&self.bounds, "+"); - } - } - } - - impl ToTokens for WhereRegionPredicate { - fn to_tokens(&self, tokens: &mut Tokens) { - self.lifetime.to_tokens(tokens); - if !self.bounds.is_empty() { - tokens.append(":"); - tokens.append_separated(&self.bounds, "+"); - } - } - } -} diff --git a/third_party/rust/syn-0.10.8/src/helper.rs b/third_party/rust/syn-0.10.8/src/helper.rs deleted file mode 100644 index bf199713a4dd..000000000000 --- a/third_party/rust/syn-0.10.8/src/helper.rs +++ /dev/null @@ -1,137 +0,0 @@ -use nom::IResult; -use space::{skip_whitespace, word_break}; - -macro_rules! punct { - ($i:expr, $punct:expr) => { - $crate::helper::punct($i, $punct) - }; -} - -pub fn punct<'a>(input: &'a str, token: &'static str) -> IResult<&'a str, &'a str> { - let input = skip_whitespace(input); - if input.starts_with(token) { - IResult::Done(&input[token.len()..], token) - } else { - IResult::Error - } -} - -macro_rules! keyword { - ($i:expr, $keyword:expr) => { - $crate::helper::keyword($i, $keyword) - }; -} - -pub fn keyword<'a>(input: &'a str, token: &'static str) -> IResult<&'a str, &'a str> { - match punct(input, token) { - IResult::Done(rest, _) => { - match word_break(rest) { - IResult::Done(_, _) => IResult::Done(rest, token), - IResult::Error => IResult::Error, - } - } - IResult::Error => IResult::Error, - } -} - -macro_rules! option { - ($i:expr, $submac:ident!( $($args:tt)* )) => { - match $submac!($i, $($args)*) { - $crate::nom::IResult::Done(i, o) => $crate::nom::IResult::Done(i, Some(o)), - $crate::nom::IResult::Error => $crate::nom::IResult::Done($i, None), - } - }; - - ($i:expr, $f:expr) => { - option!($i, call!($f)); - }; -} - -macro_rules! opt_vec { - ($i:expr, $submac:ident!( $($args:tt)* )) => { - match $submac!($i, $($args)*) { - $crate::nom::IResult::Done(i, o) => $crate::nom::IResult::Done(i, o), - $crate::nom::IResult::Error => $crate::nom::IResult::Done($i, Vec::new()), - } - }; -} - -macro_rules! epsilon { - ($i:expr,) => { - $crate::nom::IResult::Done($i, ()) - }; -} - -macro_rules! tap { - ($i:expr, $name:ident : $submac:ident!( $($args:tt)* ) => $e:expr) => { - match $submac!($i, $($args)*) { - $crate::nom::IResult::Done(i, o) => { - let $name = o; - $e; - $crate::nom::IResult::Done(i, ()) - } - $crate::nom::IResult::Error => $crate::nom::IResult::Error, - } - }; - - ($i:expr, $name:ident : $f:expr => $e:expr) => { - tap!($i, $name: call!($f) => $e); - }; -} - -macro_rules! separated_list { - ($i:expr, punct!($sep:expr), $f:expr) => { - $crate::helper::separated_list($i, $sep, $f, false) - }; -} - -macro_rules! terminated_list { - ($i:expr, punct!($sep:expr), $f:expr) => { - $crate::helper::separated_list($i, $sep, $f, true) - }; -} - -pub fn separated_list<'a, T>(mut input: &'a str, - sep: &'static str, - f: fn(&'a str) -> IResult<&'a str, T>, - terminated: bool) - -> IResult<&'a str, Vec> { - let mut res = Vec::new(); - - // get the first element - match f(input) { - IResult::Error => IResult::Done(input, Vec::new()), - IResult::Done(i, o) => { - if i.len() == input.len() { - IResult::Error - } else { - res.push(o); - input = i; - - // get the separator first - while let IResult::Done(i2, _) = punct(input, sep) { - if i2.len() == input.len() { - break; - } - - // get the element next - if let IResult::Done(i3, o3) = f(i2) { - if i3.len() == i2.len() { - break; - } - res.push(o3); - input = i3; - } else { - break; - } - } - if terminated { - if let IResult::Done(after, _) = punct(input, sep) { - input = after; - } - } - IResult::Done(input, res) - } - } - } -} diff --git a/third_party/rust/syn-0.10.8/src/ident.rs b/third_party/rust/syn-0.10.8/src/ident.rs deleted file mode 100644 index 3657add365e3..000000000000 --- a/third_party/rust/syn-0.10.8/src/ident.rs +++ /dev/null @@ -1,129 +0,0 @@ -use std::borrow::Cow; -use std::fmt::{self, Display}; - -#[derive(Debug, Clone, Eq, Hash)] -pub struct Ident(String); - -impl Ident { - pub fn new>(t: T) -> Self { - t.into() - } -} - -impl<'a> From<&'a str> for Ident { - fn from(s: &str) -> Self { - Ident(s.to_owned()) - } -} - -impl<'a> From> for Ident { - fn from(s: Cow<'a, str>) -> Self { - Ident(s.into_owned()) - } -} - -impl From for Ident { - fn from(s: String) -> Self { - Ident(s) - } -} - -impl From for Ident { - fn from(u: usize) -> Self { - Ident(u.to_string()) - } -} - -impl AsRef for Ident { - fn as_ref(&self) -> &str { - &self.0 - } -} - -impl Display for Ident { - fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> { - self.0.fmt(formatter) - } -} - -impl PartialEq for Ident - where T: AsRef -{ - fn eq(&self, other: &T) -> bool { - self.0 == other.as_ref() - } -} - -#[cfg(feature = "parsing")] -pub mod parsing { - use super::*; - use nom::IResult; - use space::skip_whitespace; - use unicode_xid::UnicodeXID; - - pub fn ident(input: &str) -> IResult<&str, Ident> { - let (rest, id) = match word(input) { - IResult::Done(rest, id) => (rest, id), - IResult::Error => return IResult::Error, - }; - - match id.as_ref() { - // From https://doc.rust-lang.org/grammar.html#keywords - "abstract" | "alignof" | "as" | "become" | "box" | "break" | "const" | "continue" | - "crate" | "do" | "else" | "enum" | "extern" | "false" | "final" | "fn" | "for" | - "if" | "impl" | "in" | "let" | "loop" | "macro" | "match" | "mod" | "move" | - "mut" | "offsetof" | "override" | "priv" | "proc" | "pub" | "pure" | "ref" | - "return" | "Self" | "self" | "sizeof" | "static" | "struct" | "super" | "trait" | - "true" | "type" | "typeof" | "unsafe" | "unsized" | "use" | "virtual" | "where" | - "while" | "yield" => IResult::Error, - _ => IResult::Done(rest, id), - } - } - - pub fn word(mut input: &str) -> IResult<&str, Ident> { - input = skip_whitespace(input); - - let mut chars = input.char_indices(); - match chars.next() { - Some((_, ch)) if UnicodeXID::is_xid_start(ch) || ch == '_' => {} - _ => return IResult::Error, - } - - while let Some((i, ch)) = chars.next() { - if !UnicodeXID::is_xid_continue(ch) { - return IResult::Done(&input[i..], input[..i].into()); - } - } - - IResult::Done("", input.into()) - } - - #[cfg(feature = "full")] - pub fn wordlike(mut input: &str) -> IResult<&str, Ident> { - input = skip_whitespace(input); - - for (i, ch) in input.char_indices() { - if !UnicodeXID::is_xid_start(ch) && !UnicodeXID::is_xid_continue(ch) { - return if i == 0 { - IResult::Error - } else { - IResult::Done(&input[i..], input[..i].into()) - }; - } - } - - IResult::Done("", input.into()) - } -} - -#[cfg(feature = "printing")] -mod printing { - use super::*; - use quote::{Tokens, ToTokens}; - - impl ToTokens for Ident { - fn to_tokens(&self, tokens: &mut Tokens) { - tokens.append(self.as_ref()) - } - } -} diff --git a/third_party/rust/syn-0.10.8/src/item.rs b/third_party/rust/syn-0.10.8/src/item.rs deleted file mode 100644 index 00d537aa9522..000000000000 --- a/third_party/rust/syn-0.10.8/src/item.rs +++ /dev/null @@ -1,1477 +0,0 @@ -use super::*; - -/// An item -/// -/// The name might be a dummy name in case of anonymous items -#[derive(Debug, Clone, Eq, PartialEq, Hash)] -pub struct Item { - pub ident: Ident, - pub vis: Visibility, - pub attrs: Vec, - pub node: ItemKind, -} - -#[derive(Debug, Clone, Eq, PartialEq, Hash)] -pub enum ItemKind { - /// An`extern crate` item, with optional original crate name. - /// - /// E.g. `extern crate foo` or `extern crate foo_bar as foo` - ExternCrate(Option), - /// A use declaration (`use` or `pub use`) item. - /// - /// E.g. `use foo;`, `use foo::bar;` or `use foo::bar as FooBar;` - Use(Box), - /// A static item (`static` or `pub static`). - /// - /// E.g. `static FOO: i32 = 42;` or `static FOO: &'static str = "bar";` - Static(Box, Mutability, Box), - /// A constant item (`const` or `pub const`). - /// - /// E.g. `const FOO: i32 = 42;` - Const(Box, Box), - /// A function declaration (`fn` or `pub fn`). - /// - /// E.g. `fn foo(bar: usize) -> usize { .. }` - Fn(Box, Unsafety, Constness, Option, Generics, Box), - /// A module declaration (`mod` or `pub mod`). - /// - /// E.g. `mod foo;` or `mod foo { .. }` - Mod(Option>), - /// An external module (`extern` or `pub extern`). - /// - /// E.g. `extern {}` or `extern "C" {}` - ForeignMod(ForeignMod), - /// A type alias (`type` or `pub type`). - /// - /// E.g. `type Foo = Bar;` - Ty(Box, Generics), - /// An enum definition (`enum` or `pub enum`). - /// - /// E.g. `enum Foo { C, D }` - Enum(Vec, Generics), - /// A struct definition (`struct` or `pub struct`). - /// - /// E.g. `struct Foo { x: A }` - Struct(VariantData, Generics), - /// A union definition (`union` or `pub union`). - /// - /// E.g. `union Foo { x: A, y: B }` - Union(VariantData, Generics), - /// A Trait declaration (`trait` or `pub trait`). - /// - /// E.g. `trait Foo { .. }` or `trait Foo { .. }` - Trait(Unsafety, Generics, Vec, Vec), - /// Default trait implementation. - /// - /// E.g. `impl Trait for .. {}` or `impl Trait for .. {}` - DefaultImpl(Unsafety, Path), - /// An implementation. - /// - /// E.g. `impl Foo { .. }` or `impl Trait for Foo { .. }` - Impl(Unsafety, - ImplPolarity, - Generics, - Option, // (optional) trait this impl implements - Box, // self - Vec), - /// A macro invocation (which includes macro definition). - /// - /// E.g. `macro_rules! foo { .. }` or `foo!(..)` - Mac(Mac), -} - -impl From for Item { - fn from(input: MacroInput) -> Item { - Item { - ident: input.ident, - vis: input.vis, - attrs: input.attrs, - node: match input.body { - Body::Enum(variants) => ItemKind::Enum(variants, input.generics), - Body::Struct(variant_data) => ItemKind::Struct(variant_data, input.generics), - }, - } - } -} - -#[derive(Debug, Clone, Eq, PartialEq, Hash)] -pub enum ViewPath { - /// `foo::bar::baz as quux` - /// - /// or just - /// - /// `foo::bar::baz` (with `as baz` implicitly on the right) - Simple(Path, Option), - - /// `foo::bar::*` - Glob(Path), - - /// `foo::bar::{a, b, c}` - List(Path, Vec), -} - -#[derive(Debug, Clone, Eq, PartialEq, Hash)] -pub struct PathListItem { - pub name: Ident, - /// renamed in list, e.g. `use foo::{bar as baz};` - pub rename: Option, -} - -#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] -pub enum Constness { - Const, - NotConst, -} - -#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] -pub enum Defaultness { - Default, - Final, -} - -/// Foreign module declaration. -/// -/// E.g. `extern { .. }` or `extern "C" { .. }` -#[derive(Debug, Clone, Eq, PartialEq, Hash)] -pub struct ForeignMod { - pub abi: Abi, - pub items: Vec, -} - -#[derive(Debug, Clone, Eq, PartialEq, Hash)] -pub struct ForeignItem { - pub ident: Ident, - pub attrs: Vec, - pub node: ForeignItemKind, - pub vis: Visibility, -} - -/// An item within an `extern` block -#[derive(Debug, Clone, Eq, PartialEq, Hash)] -pub enum ForeignItemKind { - /// A foreign function - Fn(Box, Generics), - /// A foreign static item (`static ext: u8`) - Static(Box, Mutability), -} - -/// Represents an item declaration within a trait declaration, -/// possibly including a default implementation. A trait item is -/// either required (meaning it doesn't have an implementation, just a -/// signature) or provided (meaning it has a default implementation). -#[derive(Debug, Clone, Eq, PartialEq, Hash)] -pub struct TraitItem { - pub ident: Ident, - pub attrs: Vec, - pub node: TraitItemKind, -} - -#[derive(Debug, Clone, Eq, PartialEq, Hash)] -pub enum TraitItemKind { - Const(Ty, Option), - Method(MethodSig, Option), - Type(Vec, Option), - Macro(Mac), -} - -#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] -pub enum ImplPolarity { - /// `impl Trait for Type` - Positive, - /// `impl !Trait for Type` - Negative, -} - -#[derive(Debug, Clone, Eq, PartialEq, Hash)] -pub struct ImplItem { - pub ident: Ident, - pub vis: Visibility, - pub defaultness: Defaultness, - pub attrs: Vec, - pub node: ImplItemKind, -} - -#[derive(Debug, Clone, Eq, PartialEq, Hash)] -pub enum ImplItemKind { - Const(Ty, Expr), - Method(MethodSig, Block), - Type(Ty), - Macro(Mac), -} - -/// Represents a method's signature in a trait declaration, -/// or in an implementation. -#[derive(Debug, Clone, Eq, PartialEq, Hash)] -pub struct MethodSig { - pub unsafety: Unsafety, - pub constness: Constness, - pub abi: Option, - pub decl: FnDecl, - pub generics: Generics, -} - -/// Header (not the body) of a function declaration. -/// -/// E.g. `fn foo(bar: baz)` -#[derive(Debug, Clone, Eq, PartialEq, Hash)] -pub struct FnDecl { - pub inputs: Vec, - pub output: FunctionRetTy, - pub variadic: bool, -} - -/// An argument in a function header. -/// -/// E.g. `bar: usize` as in `fn foo(bar: usize)` -#[derive(Debug, Clone, Eq, PartialEq, Hash)] -pub enum FnArg { - SelfRef(Option, Mutability), - SelfValue(Mutability), - Captured(Pat, Ty), - Ignored(Ty), -} - -#[cfg(feature = "parsing")] -pub mod parsing { - use super::*; - use {Block, DelimToken, FunctionRetTy, Generics, Ident, Mac, Path, TokenTree, VariantData, - Visibility}; - use attr::parsing::{inner_attr, outer_attr}; - use data::parsing::{struct_like_body, visibility}; - use expr::parsing::{expr, pat, within_block}; - use generics::parsing::{generics, lifetime, ty_param_bound, where_clause}; - use ident::parsing::ident; - use mac::parsing::delimited; - use macro_input::{Body, MacroInput}; - use macro_input::parsing::macro_input; - use ty::parsing::{abi, mutability, path, ty, unsafety}; - - named!(pub item -> Item, alt!( - item_extern_crate - | - item_use - | - item_static - | - item_const - | - item_fn - | - item_mod - | - item_foreign_mod - | - item_ty - | - item_struct_or_enum - | - item_union - | - item_trait - | - item_default_impl - | - item_impl - | - item_mac - )); - - named!(pub items -> Vec, many0!(item)); - - named!(item_mac -> Item, do_parse!( - attrs: many0!(outer_attr) >> - path: ident >> - punct!("!") >> - name: option!(ident) >> - body: delimited >> - cond!(match body.delim { - DelimToken::Paren | DelimToken::Bracket => true, - DelimToken::Brace => false, - }, punct!(";")) >> - (Item { - ident: name.unwrap_or_else(|| Ident::new("")), - vis: Visibility::Inherited, - attrs: attrs, - node: ItemKind::Mac(Mac { - path: path.into(), - tts: vec![TokenTree::Delimited(body)], - }), - }) - )); - - named!(item_extern_crate -> Item, do_parse!( - attrs: many0!(outer_attr) >> - vis: visibility >> - keyword!("extern") >> - keyword!("crate") >> - id: ident >> - rename: option!(preceded!( - keyword!("as"), - ident - )) >> - punct!(";") >> - ({ - let (name, original_name) = match rename { - Some(rename) => (rename, Some(id)), - None => (id, None), - }; - Item { - ident: name, - vis: vis, - attrs: attrs, - node: ItemKind::ExternCrate(original_name), - } - }) - )); - - named!(item_use -> Item, do_parse!( - attrs: many0!(outer_attr) >> - vis: visibility >> - keyword!("use") >> - what: view_path >> - punct!(";") >> - (Item { - ident: "".into(), - vis: vis, - attrs: attrs, - node: ItemKind::Use(Box::new(what)), - }) - )); - - named!(view_path -> ViewPath, alt!( - view_path_glob - | - view_path_list - | - view_path_list_root - | - view_path_simple // must be last - )); - - - named!(view_path_simple -> ViewPath, do_parse!( - path: path >> - rename: option!(preceded!(keyword!("as"), ident)) >> - (ViewPath::Simple(path, rename)) - )); - - named!(view_path_glob -> ViewPath, do_parse!( - path: path >> - punct!("::") >> - punct!("*") >> - (ViewPath::Glob(path)) - )); - - named!(view_path_list -> ViewPath, do_parse!( - path: path >> - punct!("::") >> - punct!("{") >> - items: terminated_list!(punct!(","), path_list_item) >> - punct!("}") >> - (ViewPath::List(path, items)) - )); - - named!(view_path_list_root -> ViewPath, do_parse!( - global: option!(punct!("::")) >> - punct!("{") >> - items: terminated_list!(punct!(","), path_list_item) >> - punct!("}") >> - (ViewPath::List(Path { - global: global.is_some(), - segments: Vec::new(), - }, items)) - )); - - named!(path_list_item -> PathListItem, do_parse!( - name: alt!( - ident - | - map!(keyword!("self"), Into::into) - ) >> - rename: option!(preceded!(keyword!("as"), ident)) >> - (PathListItem { - name: name, - rename: rename, - }) - )); - - named!(item_static -> Item, do_parse!( - attrs: many0!(outer_attr) >> - vis: visibility >> - keyword!("static") >> - mutability: mutability >> - id: ident >> - punct!(":") >> - ty: ty >> - punct!("=") >> - value: expr >> - punct!(";") >> - (Item { - ident: id, - vis: vis, - attrs: attrs, - node: ItemKind::Static(Box::new(ty), mutability, Box::new(value)), - }) - )); - - named!(item_const -> Item, do_parse!( - attrs: many0!(outer_attr) >> - vis: visibility >> - keyword!("const") >> - id: ident >> - punct!(":") >> - ty: ty >> - punct!("=") >> - value: expr >> - punct!(";") >> - (Item { - ident: id, - vis: vis, - attrs: attrs, - node: ItemKind::Const(Box::new(ty), Box::new(value)), - }) - )); - - named!(item_fn -> Item, do_parse!( - outer_attrs: many0!(outer_attr) >> - vis: visibility >> - constness: constness >> - unsafety: unsafety >> - abi: option!(abi) >> - keyword!("fn") >> - name: ident >> - generics: generics >> - punct!("(") >> - inputs: terminated_list!(punct!(","), fn_arg) >> - punct!(")") >> - ret: option!(preceded!(punct!("->"), ty)) >> - where_clause: where_clause >> - punct!("{") >> - inner_attrs: many0!(inner_attr) >> - stmts: within_block >> - punct!("}") >> - (Item { - ident: name, - vis: vis, - attrs: { - let mut attrs = outer_attrs; - attrs.extend(inner_attrs); - attrs - }, - node: ItemKind::Fn( - Box::new(FnDecl { - inputs: inputs, - output: ret.map(FunctionRetTy::Ty).unwrap_or(FunctionRetTy::Default), - variadic: false, - }), - unsafety, - constness, - abi, - Generics { - where_clause: where_clause, - .. generics - }, - Box::new(Block { - stmts: stmts, - }), - ), - }) - )); - - named!(fn_arg -> FnArg, alt!( - do_parse!( - punct!("&") >> - lt: option!(lifetime) >> - mutability: mutability >> - keyword!("self") >> - not!(peek!(punct!(":"))) >> - (FnArg::SelfRef(lt, mutability)) - ) - | - do_parse!( - mutability: mutability >> - keyword!("self") >> - not!(peek!(punct!(":"))) >> - (FnArg::SelfValue(mutability)) - ) - | - do_parse!( - pat: pat >> - punct!(":") >> - ty: ty >> - (FnArg::Captured(pat, ty)) - ) - | - ty => { FnArg::Ignored } - )); - - named!(item_mod -> Item, do_parse!( - outer_attrs: many0!(outer_attr) >> - vis: visibility >> - keyword!("mod") >> - id: ident >> - content: alt!( - punct!(";") => { |_| None } - | - delimited!( - punct!("{"), - tuple!( - many0!(inner_attr), - items - ), - punct!("}") - ) => { Some } - ) >> - (match content { - Some((inner_attrs, items)) => Item { - ident: id, - vis: vis, - attrs: { - let mut attrs = outer_attrs; - attrs.extend(inner_attrs); - attrs - }, - node: ItemKind::Mod(Some(items)), - }, - None => Item { - ident: id, - vis: vis, - attrs: outer_attrs, - node: ItemKind::Mod(None), - }, - }) - )); - - named!(item_foreign_mod -> Item, do_parse!( - attrs: many0!(outer_attr) >> - abi: abi >> - punct!("{") >> - items: many0!(foreign_item) >> - punct!("}") >> - (Item { - ident: "".into(), - vis: Visibility::Inherited, - attrs: attrs, - node: ItemKind::ForeignMod(ForeignMod { - abi: abi, - items: items, - }), - }) - )); - - named!(foreign_item -> ForeignItem, alt!( - foreign_fn - | - foreign_static - )); - - named!(foreign_fn -> ForeignItem, do_parse!( - attrs: many0!(outer_attr) >> - vis: visibility >> - keyword!("fn") >> - name: ident >> - generics: generics >> - punct!("(") >> - inputs: separated_list!(punct!(","), fn_arg) >> - trailing_comma: option!(punct!(",")) >> - variadic: option!(cond_reduce!(trailing_comma.is_some(), punct!("..."))) >> - punct!(")") >> - ret: option!(preceded!(punct!("->"), ty)) >> - where_clause: where_clause >> - punct!(";") >> - (ForeignItem { - ident: name, - attrs: attrs, - node: ForeignItemKind::Fn( - Box::new(FnDecl { - inputs: inputs, - output: ret.map(FunctionRetTy::Ty).unwrap_or(FunctionRetTy::Default), - variadic: variadic.is_some(), - }), - Generics { - where_clause: where_clause, - .. generics - }, - ), - vis: vis, - }) - )); - - named!(foreign_static -> ForeignItem, do_parse!( - attrs: many0!(outer_attr) >> - vis: visibility >> - keyword!("static") >> - mutability: mutability >> - id: ident >> - punct!(":") >> - ty: ty >> - punct!(";") >> - (ForeignItem { - ident: id, - attrs: attrs, - node: ForeignItemKind::Static(Box::new(ty), mutability), - vis: vis, - }) - )); - - named!(item_ty -> Item, do_parse!( - attrs: many0!(outer_attr) >> - vis: visibility >> - keyword!("type") >> - id: ident >> - generics: generics >> - where_clause: where_clause >> - punct!("=") >> - ty: ty >> - punct!(";") >> - (Item { - ident: id, - vis: vis, - attrs: attrs, - node: ItemKind::Ty( - Box::new(ty), - Generics { - where_clause: where_clause, - ..generics - }, - ), - }) - )); - - named!(item_struct_or_enum -> Item, map!( - macro_input, - |def: MacroInput| Item { - ident: def.ident, - vis: def.vis, - attrs: def.attrs, - node: match def.body { - Body::Enum(variants) => { - ItemKind::Enum(variants, def.generics) - } - Body::Struct(variant_data) => { - ItemKind::Struct(variant_data, def.generics) - } - } - } - )); - - named!(item_union -> Item, do_parse!( - attrs: many0!(outer_attr) >> - vis: visibility >> - keyword!("union") >> - id: ident >> - generics: generics >> - where_clause: where_clause >> - fields: struct_like_body >> - (Item { - ident: id, - vis: vis, - attrs: attrs, - node: ItemKind::Union( - VariantData::Struct(fields), - Generics { - where_clause: where_clause, - .. generics - }, - ), - }) - )); - - named!(item_trait -> Item, do_parse!( - attrs: many0!(outer_attr) >> - vis: visibility >> - unsafety: unsafety >> - keyword!("trait") >> - id: ident >> - generics: generics >> - bounds: opt_vec!(preceded!( - punct!(":"), - separated_nonempty_list!(punct!("+"), ty_param_bound) - )) >> - where_clause: where_clause >> - punct!("{") >> - body: many0!(trait_item) >> - punct!("}") >> - (Item { - ident: id, - vis: vis, - attrs: attrs, - node: ItemKind::Trait( - unsafety, - Generics { - where_clause: where_clause, - .. generics - }, - bounds, - body, - ), - }) - )); - - named!(item_default_impl -> Item, do_parse!( - attrs: many0!(outer_attr) >> - unsafety: unsafety >> - keyword!("impl") >> - path: path >> - keyword!("for") >> - punct!("..") >> - punct!("{") >> - punct!("}") >> - (Item { - ident: "".into(), - vis: Visibility::Inherited, - attrs: attrs, - node: ItemKind::DefaultImpl(unsafety, path), - }) - )); - - named!(trait_item -> TraitItem, alt!( - trait_item_const - | - trait_item_method - | - trait_item_type - | - trait_item_mac - )); - - named!(trait_item_const -> TraitItem, do_parse!( - attrs: many0!(outer_attr) >> - keyword!("const") >> - id: ident >> - punct!(":") >> - ty: ty >> - value: option!(preceded!(punct!("="), expr)) >> - punct!(";") >> - (TraitItem { - ident: id, - attrs: attrs, - node: TraitItemKind::Const(ty, value), - }) - )); - - named!(trait_item_method -> TraitItem, do_parse!( - outer_attrs: many0!(outer_attr) >> - constness: constness >> - unsafety: unsafety >> - abi: option!(abi) >> - keyword!("fn") >> - name: ident >> - generics: generics >> - punct!("(") >> - inputs: terminated_list!(punct!(","), fn_arg) >> - punct!(")") >> - ret: option!(preceded!(punct!("->"), ty)) >> - where_clause: where_clause >> - body: option!(delimited!( - punct!("{"), - tuple!(many0!(inner_attr), within_block), - punct!("}") - )) >> - cond!(body.is_none(), punct!(";")) >> - ({ - let (inner_attrs, stmts) = match body { - Some((inner_attrs, stmts)) => (inner_attrs, Some(stmts)), - None => (Vec::new(), None), - }; - TraitItem { - ident: name, - attrs: { - let mut attrs = outer_attrs; - attrs.extend(inner_attrs); - attrs - }, - node: TraitItemKind::Method( - MethodSig { - unsafety: unsafety, - constness: constness, - abi: abi, - decl: FnDecl { - inputs: inputs, - output: ret.map(FunctionRetTy::Ty).unwrap_or(FunctionRetTy::Default), - variadic: false, - }, - generics: Generics { - where_clause: where_clause, - .. generics - }, - }, - stmts.map(|stmts| Block { stmts: stmts }), - ), - } - }) - )); - - named!(trait_item_type -> TraitItem, do_parse!( - attrs: many0!(outer_attr) >> - keyword!("type") >> - id: ident >> - bounds: opt_vec!(preceded!( - punct!(":"), - separated_nonempty_list!(punct!("+"), ty_param_bound) - )) >> - default: option!(preceded!(punct!("="), ty)) >> - punct!(";") >> - (TraitItem { - ident: id, - attrs: attrs, - node: TraitItemKind::Type(bounds, default), - }) - )); - - named!(trait_item_mac -> TraitItem, do_parse!( - attrs: many0!(outer_attr) >> - id: ident >> - punct!("!") >> - body: delimited >> - cond!(match body.delim { - DelimToken::Paren | DelimToken::Bracket => true, - DelimToken::Brace => false, - }, punct!(";")) >> - (TraitItem { - ident: id.clone(), - attrs: attrs, - node: TraitItemKind::Macro(Mac { - path: id.into(), - tts: vec![TokenTree::Delimited(body)], - }), - }) - )); - - named!(item_impl -> Item, do_parse!( - attrs: many0!(outer_attr) >> - unsafety: unsafety >> - keyword!("impl") >> - generics: generics >> - polarity_path: alt!( - do_parse!( - polarity: impl_polarity >> - path: path >> - keyword!("for") >> - ((polarity, Some(path))) - ) - | - epsilon!() => { |_| (ImplPolarity::Positive, None) } - ) >> - self_ty: ty >> - where_clause: where_clause >> - punct!("{") >> - body: many0!(impl_item) >> - punct!("}") >> - (Item { - ident: "".into(), - vis: Visibility::Inherited, - attrs: attrs, - node: ItemKind::Impl( - unsafety, - polarity_path.0, - Generics { - where_clause: where_clause, - .. generics - }, - polarity_path.1, - Box::new(self_ty), - body, - ), - }) - )); - - named!(impl_item -> ImplItem, alt!( - impl_item_const - | - impl_item_method - | - impl_item_type - | - impl_item_macro - )); - - named!(impl_item_const -> ImplItem, do_parse!( - attrs: many0!(outer_attr) >> - vis: visibility >> - defaultness: defaultness >> - keyword!("const") >> - id: ident >> - punct!(":") >> - ty: ty >> - punct!("=") >> - value: expr >> - punct!(";") >> - (ImplItem { - ident: id, - vis: vis, - defaultness: defaultness, - attrs: attrs, - node: ImplItemKind::Const(ty, value), - }) - )); - - named!(impl_item_method -> ImplItem, do_parse!( - outer_attrs: many0!(outer_attr) >> - vis: visibility >> - defaultness: defaultness >> - constness: constness >> - unsafety: unsafety >> - abi: option!(abi) >> - keyword!("fn") >> - name: ident >> - generics: generics >> - punct!("(") >> - inputs: terminated_list!(punct!(","), fn_arg) >> - punct!(")") >> - ret: option!(preceded!(punct!("->"), ty)) >> - where_clause: where_clause >> - punct!("{") >> - inner_attrs: many0!(inner_attr) >> - stmts: within_block >> - punct!("}") >> - (ImplItem { - ident: name, - vis: vis, - defaultness: defaultness, - attrs: { - let mut attrs = outer_attrs; - attrs.extend(inner_attrs); - attrs - }, - node: ImplItemKind::Method( - MethodSig { - unsafety: unsafety, - constness: constness, - abi: abi, - decl: FnDecl { - inputs: inputs, - output: ret.map(FunctionRetTy::Ty).unwrap_or(FunctionRetTy::Default), - variadic: false, - }, - generics: Generics { - where_clause: where_clause, - .. generics - }, - }, - Block { - stmts: stmts, - }, - ), - }) - )); - - named!(impl_item_type -> ImplItem, do_parse!( - attrs: many0!(outer_attr) >> - vis: visibility >> - defaultness: defaultness >> - keyword!("type") >> - id: ident >> - punct!("=") >> - ty: ty >> - punct!(";") >> - (ImplItem { - ident: id, - vis: vis, - defaultness: defaultness, - attrs: attrs, - node: ImplItemKind::Type(ty), - }) - )); - - named!(impl_item_macro -> ImplItem, do_parse!( - attrs: many0!(outer_attr) >> - id: ident >> - punct!("!") >> - body: delimited >> - cond!(match body.delim { - DelimToken::Paren | DelimToken::Bracket => true, - DelimToken::Brace => false, - }, punct!(";")) >> - (ImplItem { - ident: id.clone(), - vis: Visibility::Inherited, - defaultness: Defaultness::Final, - attrs: attrs, - node: ImplItemKind::Macro(Mac { - path: id.into(), - tts: vec![TokenTree::Delimited(body)], - }), - }) - )); - - named!(impl_polarity -> ImplPolarity, alt!( - punct!("!") => { |_| ImplPolarity::Negative } - | - epsilon!() => { |_| ImplPolarity::Positive } - )); - - named!(constness -> Constness, alt!( - keyword!("const") => { |_| Constness::Const } - | - epsilon!() => { |_| Constness::NotConst } - )); - - named!(defaultness -> Defaultness, alt!( - keyword!("default") => { |_| Defaultness::Default } - | - epsilon!() => { |_| Defaultness::Final } - )); -} - -#[cfg(feature = "printing")] -mod printing { - use super::*; - use {Delimited, DelimToken, FunctionRetTy, TokenTree}; - use attr::FilterAttrs; - use data::VariantData; - use quote::{Tokens, ToTokens}; - - impl ToTokens for Item { - fn to_tokens(&self, tokens: &mut Tokens) { - tokens.append_all(self.attrs.outer()); - match self.node { - ItemKind::ExternCrate(ref original) => { - self.vis.to_tokens(tokens); - tokens.append("extern"); - tokens.append("crate"); - if let Some(ref original) = *original { - original.to_tokens(tokens); - tokens.append("as"); - } - self.ident.to_tokens(tokens); - tokens.append(";"); - } - ItemKind::Use(ref view_path) => { - self.vis.to_tokens(tokens); - tokens.append("use"); - view_path.to_tokens(tokens); - tokens.append(";"); - } - ItemKind::Static(ref ty, ref mutability, ref expr) => { - self.vis.to_tokens(tokens); - tokens.append("static"); - mutability.to_tokens(tokens); - self.ident.to_tokens(tokens); - tokens.append(":"); - ty.to_tokens(tokens); - tokens.append("="); - expr.to_tokens(tokens); - tokens.append(";"); - } - ItemKind::Const(ref ty, ref expr) => { - self.vis.to_tokens(tokens); - tokens.append("const"); - self.ident.to_tokens(tokens); - tokens.append(":"); - ty.to_tokens(tokens); - tokens.append("="); - expr.to_tokens(tokens); - tokens.append(";"); - } - ItemKind::Fn(ref decl, unsafety, constness, ref abi, ref generics, ref block) => { - self.vis.to_tokens(tokens); - constness.to_tokens(tokens); - unsafety.to_tokens(tokens); - abi.to_tokens(tokens); - tokens.append("fn"); - self.ident.to_tokens(tokens); - generics.to_tokens(tokens); - tokens.append("("); - tokens.append_separated(&decl.inputs, ","); - tokens.append(")"); - if let FunctionRetTy::Ty(ref ty) = decl.output { - tokens.append("->"); - ty.to_tokens(tokens); - } - generics.where_clause.to_tokens(tokens); - tokens.append("{"); - tokens.append_all(self.attrs.inner()); - tokens.append_all(&block.stmts); - tokens.append("}"); - } - ItemKind::Mod(ref items) => { - self.vis.to_tokens(tokens); - tokens.append("mod"); - self.ident.to_tokens(tokens); - match *items { - Some(ref items) => { - tokens.append("{"); - tokens.append_all(self.attrs.inner()); - tokens.append_all(items); - tokens.append("}"); - } - None => tokens.append(";"), - } - } - ItemKind::ForeignMod(ref foreign_mod) => { - self.vis.to_tokens(tokens); - foreign_mod.abi.to_tokens(tokens); - tokens.append("{"); - tokens.append_all(&foreign_mod.items); - tokens.append("}"); - } - ItemKind::Ty(ref ty, ref generics) => { - self.vis.to_tokens(tokens); - tokens.append("type"); - self.ident.to_tokens(tokens); - generics.to_tokens(tokens); - generics.where_clause.to_tokens(tokens); - tokens.append("="); - ty.to_tokens(tokens); - tokens.append(";"); - } - ItemKind::Enum(ref variants, ref generics) => { - self.vis.to_tokens(tokens); - tokens.append("enum"); - self.ident.to_tokens(tokens); - generics.to_tokens(tokens); - generics.where_clause.to_tokens(tokens); - tokens.append("{"); - for variant in variants { - variant.to_tokens(tokens); - tokens.append(","); - } - tokens.append("}"); - } - ItemKind::Struct(ref variant_data, ref generics) => { - self.vis.to_tokens(tokens); - tokens.append("struct"); - self.ident.to_tokens(tokens); - generics.to_tokens(tokens); - match *variant_data { - VariantData::Struct(_) => { - generics.where_clause.to_tokens(tokens); - variant_data.to_tokens(tokens); - // no semicolon - } - VariantData::Tuple(_) => { - variant_data.to_tokens(tokens); - generics.where_clause.to_tokens(tokens); - tokens.append(";"); - } - VariantData::Unit => { - generics.where_clause.to_tokens(tokens); - tokens.append(";"); - } - } - } - ItemKind::Union(ref variant_data, ref generics) => { - self.vis.to_tokens(tokens); - tokens.append("union"); - self.ident.to_tokens(tokens); - generics.to_tokens(tokens); - generics.where_clause.to_tokens(tokens); - variant_data.to_tokens(tokens); - } - ItemKind::Trait(unsafety, ref generics, ref bound, ref items) => { - self.vis.to_tokens(tokens); - unsafety.to_tokens(tokens); - tokens.append("trait"); - self.ident.to_tokens(tokens); - generics.to_tokens(tokens); - if !bound.is_empty() { - tokens.append(":"); - tokens.append_separated(bound, "+"); - } - generics.where_clause.to_tokens(tokens); - tokens.append("{"); - tokens.append_all(items); - tokens.append("}"); - } - ItemKind::DefaultImpl(unsafety, ref path) => { - unsafety.to_tokens(tokens); - tokens.append("impl"); - path.to_tokens(tokens); - tokens.append("for"); - tokens.append(".."); - tokens.append("{"); - tokens.append("}"); - } - ItemKind::Impl(unsafety, polarity, ref generics, ref path, ref ty, ref items) => { - unsafety.to_tokens(tokens); - tokens.append("impl"); - generics.to_tokens(tokens); - if let Some(ref path) = *path { - polarity.to_tokens(tokens); - path.to_tokens(tokens); - tokens.append("for"); - } - ty.to_tokens(tokens); - generics.where_clause.to_tokens(tokens); - tokens.append("{"); - tokens.append_all(items); - tokens.append("}"); - } - ItemKind::Mac(ref mac) => { - mac.path.to_tokens(tokens); - tokens.append("!"); - self.ident.to_tokens(tokens); - for tt in &mac.tts { - tt.to_tokens(tokens); - } - match mac.tts.last() { - Some(&TokenTree::Delimited(Delimited { delim: DelimToken::Brace, .. })) => { - // no semicolon - } - _ => tokens.append(";"), - } - } - } - } - } - - impl ToTokens for ViewPath { - fn to_tokens(&self, tokens: &mut Tokens) { - match *self { - ViewPath::Simple(ref path, ref rename) => { - path.to_tokens(tokens); - if let Some(ref rename) = *rename { - tokens.append("as"); - rename.to_tokens(tokens); - } - } - ViewPath::Glob(ref path) => { - path.to_tokens(tokens); - tokens.append("::"); - tokens.append("*"); - } - ViewPath::List(ref path, ref items) => { - path.to_tokens(tokens); - if path.global || !path.segments.is_empty() { - tokens.append("::"); - } - tokens.append("{"); - tokens.append_separated(items, ","); - tokens.append("}"); - } - } - } - } - - impl ToTokens for PathListItem { - fn to_tokens(&self, tokens: &mut Tokens) { - self.name.to_tokens(tokens); - if let Some(ref rename) = self.rename { - tokens.append("as"); - rename.to_tokens(tokens); - } - } - } - - impl ToTokens for TraitItem { - fn to_tokens(&self, tokens: &mut Tokens) { - tokens.append_all(self.attrs.outer()); - match self.node { - TraitItemKind::Const(ref ty, ref expr) => { - tokens.append("const"); - self.ident.to_tokens(tokens); - tokens.append(":"); - ty.to_tokens(tokens); - if let Some(ref expr) = *expr { - tokens.append("="); - expr.to_tokens(tokens); - } - tokens.append(";"); - } - TraitItemKind::Method(ref sig, ref block) => { - sig.constness.to_tokens(tokens); - sig.unsafety.to_tokens(tokens); - sig.abi.to_tokens(tokens); - tokens.append("fn"); - self.ident.to_tokens(tokens); - sig.generics.to_tokens(tokens); - tokens.append("("); - tokens.append_separated(&sig.decl.inputs, ","); - tokens.append(")"); - if let FunctionRetTy::Ty(ref ty) = sig.decl.output { - tokens.append("->"); - ty.to_tokens(tokens); - } - sig.generics.where_clause.to_tokens(tokens); - match *block { - Some(ref block) => { - tokens.append("{"); - tokens.append_all(self.attrs.inner()); - tokens.append_all(&block.stmts); - tokens.append("}"); - } - None => tokens.append(";"), - } - } - TraitItemKind::Type(ref bound, ref default) => { - tokens.append("type"); - self.ident.to_tokens(tokens); - if !bound.is_empty() { - tokens.append(":"); - tokens.append_separated(bound, "+"); - } - if let Some(ref default) = *default { - tokens.append("="); - default.to_tokens(tokens); - } - tokens.append(";"); - } - TraitItemKind::Macro(ref mac) => { - mac.to_tokens(tokens); - match mac.tts.last() { - Some(&TokenTree::Delimited(Delimited { delim: DelimToken::Brace, .. })) => { - // no semicolon - } - _ => tokens.append(";"), - } - } - } - } - } - - impl ToTokens for ImplItem { - fn to_tokens(&self, tokens: &mut Tokens) { - tokens.append_all(self.attrs.outer()); - match self.node { - ImplItemKind::Const(ref ty, ref expr) => { - self.vis.to_tokens(tokens); - self.defaultness.to_tokens(tokens); - tokens.append("const"); - self.ident.to_tokens(tokens); - tokens.append(":"); - ty.to_tokens(tokens); - tokens.append("="); - expr.to_tokens(tokens); - tokens.append(";"); - } - ImplItemKind::Method(ref sig, ref block) => { - self.vis.to_tokens(tokens); - self.defaultness.to_tokens(tokens); - sig.constness.to_tokens(tokens); - sig.unsafety.to_tokens(tokens); - sig.abi.to_tokens(tokens); - tokens.append("fn"); - self.ident.to_tokens(tokens); - sig.generics.to_tokens(tokens); - tokens.append("("); - tokens.append_separated(&sig.decl.inputs, ","); - tokens.append(")"); - if let FunctionRetTy::Ty(ref ty) = sig.decl.output { - tokens.append("->"); - ty.to_tokens(tokens); - } - sig.generics.where_clause.to_tokens(tokens); - tokens.append("{"); - tokens.append_all(self.attrs.inner()); - tokens.append_all(&block.stmts); - tokens.append("}"); - } - ImplItemKind::Type(ref ty) => { - self.vis.to_tokens(tokens); - self.defaultness.to_tokens(tokens); - tokens.append("type"); - self.ident.to_tokens(tokens); - tokens.append("="); - ty.to_tokens(tokens); - tokens.append(";"); - } - ImplItemKind::Macro(ref mac) => { - mac.to_tokens(tokens); - match mac.tts.last() { - Some(&TokenTree::Delimited(Delimited { delim: DelimToken::Brace, .. })) => { - // no semicolon - } - _ => tokens.append(";"), - } - } - } - } - } - - impl ToTokens for ForeignItem { - fn to_tokens(&self, tokens: &mut Tokens) { - tokens.append_all(self.attrs.outer()); - match self.node { - ForeignItemKind::Fn(ref decl, ref generics) => { - self.vis.to_tokens(tokens); - tokens.append("fn"); - self.ident.to_tokens(tokens); - generics.to_tokens(tokens); - tokens.append("("); - tokens.append_separated(&decl.inputs, ","); - if decl.variadic { - if !decl.inputs.is_empty() { - tokens.append(","); - } - tokens.append("..."); - } - tokens.append(")"); - if let FunctionRetTy::Ty(ref ty) = decl.output { - tokens.append("->"); - ty.to_tokens(tokens); - } - generics.where_clause.to_tokens(tokens); - tokens.append(";"); - } - ForeignItemKind::Static(ref ty, mutability) => { - self.vis.to_tokens(tokens); - tokens.append("static"); - mutability.to_tokens(tokens); - self.ident.to_tokens(tokens); - tokens.append(":"); - ty.to_tokens(tokens); - tokens.append(";"); - } - } - } - } - - impl ToTokens for FnArg { - fn to_tokens(&self, tokens: &mut Tokens) { - match *self { - FnArg::SelfRef(ref lifetime, mutability) => { - tokens.append("&"); - lifetime.to_tokens(tokens); - mutability.to_tokens(tokens); - tokens.append("self"); - } - FnArg::SelfValue(mutability) => { - mutability.to_tokens(tokens); - tokens.append("self"); - } - FnArg::Captured(ref pat, ref ty) => { - pat.to_tokens(tokens); - tokens.append(":"); - ty.to_tokens(tokens); - } - FnArg::Ignored(ref ty) => { - ty.to_tokens(tokens); - } - } - } - } - - impl ToTokens for Constness { - fn to_tokens(&self, tokens: &mut Tokens) { - match *self { - Constness::Const => tokens.append("const"), - Constness::NotConst => { - // nothing - } - } - } - } - - impl ToTokens for Defaultness { - fn to_tokens(&self, tokens: &mut Tokens) { - match *self { - Defaultness::Default => tokens.append("default"), - Defaultness::Final => { - // nothing - } - } - } - } - - impl ToTokens for ImplPolarity { - fn to_tokens(&self, tokens: &mut Tokens) { - match *self { - ImplPolarity::Negative => tokens.append("!"), - ImplPolarity::Positive => { - // nothing - } - } - } - } -} diff --git a/third_party/rust/syn-0.10.8/src/krate.rs b/third_party/rust/syn-0.10.8/src/krate.rs deleted file mode 100644 index 7ed16b521d6a..000000000000 --- a/third_party/rust/syn-0.10.8/src/krate.rs +++ /dev/null @@ -1,57 +0,0 @@ -use super::*; - -#[derive(Debug, Clone, Eq, PartialEq, Hash)] -pub struct Crate { - pub shebang: Option, - pub attrs: Vec, - pub items: Vec, -} - -#[cfg(feature = "parsing")] -pub mod parsing { - use super::*; - use attr::parsing::inner_attr; - use item::parsing::items; - - named!(pub krate -> Crate, do_parse!( - option!(byte_order_mark) >> - shebang: option!(shebang) >> - attrs: many0!(inner_attr) >> - items: items >> - (Crate { - shebang: shebang, - attrs: attrs, - items: items, - }) - )); - - named!(byte_order_mark -> &str, tag!("\u{feff}")); - - named!(shebang -> String, do_parse!( - tag!("#!") >> - not!(peek!(tag!("["))) >> - content: take_until!("\n") >> - (format!("#!{}", content)) - )); -} - -#[cfg(feature = "printing")] -mod printing { - use super::*; - use attr::FilterAttrs; - use quote::{Tokens, ToTokens}; - - impl ToTokens for Crate { - fn to_tokens(&self, tokens: &mut Tokens) { - if let Some(ref shebang) = self.shebang { - tokens.append(&format!("{}\n", shebang)); - } - for attr in self.attrs.inner() { - attr.to_tokens(tokens); - } - for item in &self.items { - item.to_tokens(tokens); - } - } - } -} diff --git a/third_party/rust/syn-0.10.8/src/lib.rs b/third_party/rust/syn-0.10.8/src/lib.rs deleted file mode 100644 index 41b5ae058a3e..000000000000 --- a/third_party/rust/syn-0.10.8/src/lib.rs +++ /dev/null @@ -1,170 +0,0 @@ -#![cfg_attr(feature = "clippy", feature(plugin))] -#![cfg_attr(feature = "clippy", plugin(clippy))] - -#[cfg(feature = "printing")] -#[macro_use] -extern crate quote; - -#[cfg(feature = "pretty")] -extern crate syntex_syntax as syntax; - -#[cfg(feature = "parsing")] -extern crate unicode_xid; - -#[cfg(feature = "parsing")] -#[macro_use] -mod nom; - -#[cfg(feature = "parsing")] -#[macro_use] -mod helper; - -#[cfg(feature = "aster")] -pub mod aster; - -mod attr; -pub use attr::{Attribute, AttrStyle, MetaItem, NestedMetaItem}; - -mod constant; -pub use constant::ConstExpr; - -mod data; -pub use data::{Field, Variant, VariantData, Visibility}; - -#[cfg(feature = "parsing")] -mod escape; - -#[cfg(feature = "full")] -mod expr; -#[cfg(feature = "full")] -pub use expr::{Arm, BindingMode, Block, BlockCheckMode, CaptureBy, Expr, ExprKind, FieldPat, - FieldValue, Local, MacStmtStyle, Pat, RangeLimits, Stmt}; - -mod generics; -pub use generics::{Generics, Lifetime, LifetimeDef, TraitBoundModifier, TyParam, TyParamBound, - WhereBoundPredicate, WhereClause, WherePredicate, WhereRegionPredicate}; -#[cfg(feature = "printing")] -pub use generics::{ImplGenerics, TyGenerics}; - -mod ident; -pub use ident::Ident; - -#[cfg(feature = "full")] -mod item; -#[cfg(feature = "full")] -pub use item::{Constness, Defaultness, FnArg, FnDecl, ForeignItemKind, ForeignItem, ForeignMod, - ImplItem, ImplItemKind, ImplPolarity, Item, ItemKind, MethodSig, PathListItem, - TraitItem, TraitItemKind, ViewPath}; - -#[cfg(feature = "full")] -mod krate; -#[cfg(feature = "full")] -pub use krate::Crate; - -mod lit; -pub use lit::{FloatTy, IntTy, Lit, StrStyle}; - -#[cfg(feature = "full")] -mod mac; -#[cfg(feature = "full")] -pub use mac::{BinOpToken, DelimToken, Delimited, Mac, Token, TokenTree}; - -mod macro_input; -pub use macro_input::{Body, MacroInput}; - -mod op; -pub use op::{BinOp, UnOp}; - -#[cfg(feature = "expand")] -mod registry; -#[cfg(feature = "expand")] -pub use registry::{CustomDerive, Expanded, Registry}; - -#[cfg(feature = "parsing")] -mod space; - -mod ty; -pub use ty::{Abi, AngleBracketedParameterData, BareFnArg, BareFnTy, FunctionRetTy, MutTy, - Mutability, ParenthesizedParameterData, Path, PathParameters, PathSegment, - PolyTraitRef, QSelf, Ty, TypeBinding, Unsafety}; - -#[cfg(feature = "visit")] -pub mod visit; - -#[cfg(feature = "parsing")] -pub use parsing::*; - -#[cfg(feature = "parsing")] -mod parsing { - use super::*; - use {generics, ident, macro_input, space, ty}; - use nom::IResult; - - #[cfg(feature = "full")] - use {expr, item, krate, mac}; - - pub fn parse_macro_input(input: &str) -> Result { - unwrap("macro input", macro_input::parsing::macro_input, input) - } - - #[cfg(feature = "full")] - pub fn parse_crate(input: &str) -> Result { - unwrap("crate", krate::parsing::krate, input) - } - - #[cfg(feature = "full")] - pub fn parse_item(input: &str) -> Result { - unwrap("item", item::parsing::item, input) - } - - #[cfg(feature = "full")] - pub fn parse_items(input: &str) -> Result, String> { - unwrap("items", item::parsing::items, input) - } - - #[cfg(feature = "full")] - pub fn parse_expr(input: &str) -> Result { - unwrap("expression", expr::parsing::expr, input) - } - - pub fn parse_type(input: &str) -> Result { - unwrap("type", ty::parsing::ty, input) - } - - pub fn parse_path(input: &str) -> Result { - unwrap("path", ty::parsing::path, input) - } - - pub fn parse_where_clause(input: &str) -> Result { - unwrap("where clause", generics::parsing::where_clause, input) - } - - #[cfg(feature = "full")] - pub fn parse_token_trees(input: &str) -> Result, String> { - unwrap("token trees", mac::parsing::token_trees, input) - } - - pub fn parse_ident(input: &str) -> Result { - unwrap("identifier", ident::parsing::ident, input) - } - - fn unwrap(name: &'static str, - f: fn(&str) -> IResult<&str, T>, - input: &str) - -> Result { - match f(input) { - IResult::Done(mut rest, t) => { - rest = space::skip_whitespace(rest); - if rest.is_empty() { - Ok(t) - } else if rest.len() == input.len() { - // parsed nothing - Err(format!("failed to parse {}: {:?}", name, rest)) - } else { - Err(format!("failed to parse tokens after {}: {:?}", name, rest)) - } - } - IResult::Error => Err(format!("failed to parse {}: {:?}", name, input)), - } - } -} diff --git a/third_party/rust/syn-0.10.8/src/lit.rs b/third_party/rust/syn-0.10.8/src/lit.rs deleted file mode 100644 index 66174105e676..000000000000 --- a/third_party/rust/syn-0.10.8/src/lit.rs +++ /dev/null @@ -1,455 +0,0 @@ -/// Literal kind. -/// -/// E.g. `"foo"`, `42`, `12.34` or `bool` -#[derive(Debug, Clone, Eq, PartialEq, Hash)] -pub enum Lit { - /// A string literal (`"foo"`) - Str(String, StrStyle), - /// A byte string (`b"foo"`) - ByteStr(Vec, StrStyle), - /// A byte char (`b'f'`) - Byte(u8), - /// A character literal (`'a'`) - Char(char), - /// An integer literal (`1`) - Int(u64, IntTy), - /// A float literal (`1f64` or `1E10f64` or `1.0E10`) - Float(String, FloatTy), - /// A boolean literal - Bool(bool), -} - -#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] -pub enum StrStyle { - /// A regular string, like `"foo"` - Cooked, - /// A raw string, like `r##"foo"##` - /// - /// The uint is the number of `#` symbols used - Raw(usize), -} - -impl From for Lit { - fn from(input: String) -> Lit { - Lit::Str(input, StrStyle::Cooked) - } -} - -impl<'a> From<&'a str> for Lit { - fn from(input: &str) -> Lit { - Lit::Str(input.into(), StrStyle::Cooked) - } -} - -impl From> for Lit { - fn from(input: Vec) -> Lit { - Lit::ByteStr(input, StrStyle::Cooked) - } -} - -impl<'a> From<&'a [u8]> for Lit { - fn from(input: &[u8]) -> Lit { - Lit::ByteStr(input.into(), StrStyle::Cooked) - } -} - -impl From for Lit { - fn from(input: char) -> Lit { - Lit::Char(input) - } -} - -impl From for Lit { - fn from(input: bool) -> Lit { - Lit::Bool(input) - } -} - -#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] -pub enum IntTy { - Isize, - I8, - I16, - I32, - I64, - Usize, - U8, - U16, - U32, - U64, - Unsuffixed, -} - -#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] -pub enum FloatTy { - F32, - F64, - Unsuffixed, -} - -macro_rules! impl_from_for_lit { - (Int, [$($rust_type:ty => $syn_type:expr),+]) => { - $( - impl From<$rust_type> for Lit { - fn from(input: $rust_type) -> Lit { - Lit::Int(input as u64, $syn_type) - } - } - )+ - }; - (Float, [$($rust_type:ty => $syn_type:expr),+]) => { - $( - impl From<$rust_type> for Lit { - fn from(input: $rust_type) -> Lit { - Lit::Float(format!("{}", input), $syn_type) - } - } - )+ - }; -} - -impl_from_for_lit! {Int, [ - isize => IntTy::Isize, - i8 => IntTy::I8, - i16 => IntTy::I16, - i32 => IntTy::I32, - i64 => IntTy::I64, - usize => IntTy::Usize, - u8 => IntTy::U8, - u16 => IntTy::U16, - u32 => IntTy::U32, - u64 => IntTy::U64 -]} - -impl_from_for_lit! {Float, [ - f32 => FloatTy::F32, - f64 => FloatTy::F64 -]} - -#[cfg(feature = "parsing")] -pub mod parsing { - use super::*; - use escape::{cooked_byte, cooked_byte_string, cooked_char, cooked_string, raw_string}; - use space::skip_whitespace; - use nom::IResult; - use unicode_xid::UnicodeXID; - - named!(pub lit -> Lit, alt!( - string - | - byte_string - | - byte - | - character - | - float // must be before int - | - int => { |(value, ty)| Lit::Int(value, ty) } - | - boolean - )); - - named!(string -> Lit, alt!( - quoted_string => { |s| Lit::Str(s, StrStyle::Cooked) } - | - preceded!( - punct!("r"), - raw_string - ) => { |(s, n)| Lit::Str(s, StrStyle::Raw(n)) } - )); - - named!(pub quoted_string -> String, delimited!( - punct!("\""), - cooked_string, - tag!("\"") - )); - - named!(byte_string -> Lit, alt!( - delimited!( - punct!("b\""), - cooked_byte_string, - tag!("\"") - ) => { |vec| Lit::ByteStr(vec, StrStyle::Cooked) } - | - preceded!( - punct!("br"), - raw_string - ) => { |(s, n): (String, _)| Lit::ByteStr(s.into_bytes(), StrStyle::Raw(n)) } - )); - - named!(byte -> Lit, do_parse!( - punct!("b") >> - tag!("'") >> - b: cooked_byte >> - tag!("'") >> - (Lit::Byte(b)) - )); - - named!(character -> Lit, do_parse!( - punct!("'") >> - ch: cooked_char >> - tag!("'") >> - (Lit::Char(ch)) - )); - - named!(float -> Lit, do_parse!( - value: float_string >> - suffix: alt!( - tag!("f32") => { |_| FloatTy::F32 } - | - tag!("f64") => { |_| FloatTy::F64 } - | - epsilon!() => { |_| FloatTy::Unsuffixed } - ) >> - (Lit::Float(value, suffix)) - )); - - named!(pub int -> (u64, IntTy), tuple!( - digits, - alt!( - tag!("isize") => { |_| IntTy::Isize } - | - tag!("i8") => { |_| IntTy::I8 } - | - tag!("i16") => { |_| IntTy::I16 } - | - tag!("i32") => { |_| IntTy::I32 } - | - tag!("i64") => { |_| IntTy::I64 } - | - tag!("usize") => { |_| IntTy::Usize } - | - tag!("u8") => { |_| IntTy::U8 } - | - tag!("u16") => { |_| IntTy::U16 } - | - tag!("u32") => { |_| IntTy::U32 } - | - tag!("u64") => { |_| IntTy::U64 } - | - epsilon!() => { |_| IntTy::Unsuffixed } - ) - )); - - named!(boolean -> Lit, alt!( - keyword!("true") => { |_| Lit::Bool(true) } - | - keyword!("false") => { |_| Lit::Bool(false) } - )); - - fn float_string(mut input: &str) -> IResult<&str, String> { - input = skip_whitespace(input); - - let mut chars = input.chars().peekable(); - match chars.next() { - Some(ch) if ch >= '0' && ch <= '9' => {} - _ => return IResult::Error, - } - - let mut len = 1; - let mut has_dot = false; - let mut has_exp = false; - while let Some(&ch) = chars.peek() { - match ch { - '0'...'9' | '_' => { - chars.next(); - len += 1; - } - '.' => { - if has_dot { - break; - } - chars.next(); - if chars.peek() - .map(|&ch| ch == '.' || UnicodeXID::is_xid_start(ch)) - .unwrap_or(false) { - return IResult::Error; - } - len += 1; - has_dot = true; - } - 'e' | 'E' => { - chars.next(); - len += 1; - has_exp = true; - break; - } - _ => break, - } - } - - let rest = &input[len..]; - if !(has_dot || has_exp || rest.starts_with("f32") || rest.starts_with("f64")) { - return IResult::Error; - } - - if has_exp { - let mut has_exp_value = false; - while let Some(&ch) = chars.peek() { - match ch { - '+' | '-' => { - if has_exp_value { - break; - } - chars.next(); - len += 1; - } - '0'...'9' => { - chars.next(); - len += 1; - has_exp_value = true; - } - '_' => { - chars.next(); - len += 1; - } - _ => break, - } - } - if !has_exp_value { - return IResult::Error; - } - } - - IResult::Done(&input[len..], input[..len].replace("_", "")) - } - - pub fn digits(mut input: &str) -> IResult<&str, u64> { - input = skip_whitespace(input); - - let base = if input.starts_with("0x") { - input = &input[2..]; - 16 - } else if input.starts_with("0o") { - input = &input[2..]; - 8 - } else if input.starts_with("0b") { - input = &input[2..]; - 2 - } else { - 10 - }; - - let mut value = 0u64; - let mut len = 0; - let mut empty = true; - for b in input.bytes() { - let digit = match b { - b'0'...b'9' => (b - b'0') as u64, - b'a'...b'f' => 10 + (b - b'a') as u64, - b'A'...b'F' => 10 + (b - b'A') as u64, - b'_' => { - if empty && base == 10 { - return IResult::Error; - } - len += 1; - continue; - } - _ => break, - }; - if digit >= base { - return IResult::Error; - } - value = match value.checked_mul(base) { - Some(value) => value, - None => return IResult::Error, - }; - value = match value.checked_add(digit) { - Some(value) => value, - None => return IResult::Error, - }; - len += 1; - empty = false; - } - if empty { - IResult::Error - } else { - IResult::Done(&input[len..], value) - } - } -} - -#[cfg(feature = "printing")] -mod printing { - use super::*; - use quote::{Tokens, ToTokens}; - use std::{ascii, iter}; - use std::fmt::{self, Display}; - use std::str; - - impl ToTokens for Lit { - fn to_tokens(&self, tokens: &mut Tokens) { - match *self { - Lit::Str(ref s, StrStyle::Cooked) => s.to_tokens(tokens), - Lit::Str(ref s, StrStyle::Raw(n)) => { - tokens.append(&format!("r{delim}\"{string}\"{delim}", - delim = iter::repeat("#").take(n).collect::(), - string = s)); - } - Lit::ByteStr(ref v, StrStyle::Cooked) => { - let mut escaped = "b\"".to_string(); - for &ch in v.iter() { - match ch { - 0 => escaped.push_str(r"\0"), - b'\'' => escaped.push('\''), - _ => escaped.extend(ascii::escape_default(ch).map(|c| c as char)), - } - } - escaped.push('"'); - tokens.append(&escaped); - } - Lit::ByteStr(ref vec, StrStyle::Raw(n)) => { - tokens.append(&format!("br{delim}\"{string}\"{delim}", - delim = iter::repeat("#").take(n).collect::(), - string = str::from_utf8(vec).unwrap())); - } - Lit::Byte(b) => { - match b { - 0 => tokens.append(r"b'\0'"), - b'\"' => tokens.append("b'\"'"), - _ => { - let mut escaped = "b'".to_string(); - escaped.extend(ascii::escape_default(b).map(|c| c as char)); - escaped.push('\''); - tokens.append(&escaped); - } - } - } - Lit::Char(ch) => ch.to_tokens(tokens), - Lit::Int(value, ty) => tokens.append(&format!("{}{}", value, ty)), - Lit::Float(ref value, ty) => tokens.append(&format!("{}{}", value, ty)), - Lit::Bool(true) => tokens.append("true"), - Lit::Bool(false) => tokens.append("false"), - } - } - } - - impl Display for IntTy { - fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> { - match *self { - IntTy::Isize => formatter.write_str("isize"), - IntTy::I8 => formatter.write_str("i8"), - IntTy::I16 => formatter.write_str("i16"), - IntTy::I32 => formatter.write_str("i32"), - IntTy::I64 => formatter.write_str("i64"), - IntTy::Usize => formatter.write_str("usize"), - IntTy::U8 => formatter.write_str("u8"), - IntTy::U16 => formatter.write_str("u16"), - IntTy::U32 => formatter.write_str("u32"), - IntTy::U64 => formatter.write_str("u64"), - IntTy::Unsuffixed => Ok(()), - } - } - } - - impl Display for FloatTy { - fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> { - match *self { - FloatTy::F32 => formatter.write_str("f32"), - FloatTy::F64 => formatter.write_str("f64"), - FloatTy::Unsuffixed => Ok(()), - } - } - } -} diff --git a/third_party/rust/syn-0.10.8/src/mac.rs b/third_party/rust/syn-0.10.8/src/mac.rs deleted file mode 100644 index 642f7bce4c2b..000000000000 --- a/third_party/rust/syn-0.10.8/src/mac.rs +++ /dev/null @@ -1,429 +0,0 @@ -use super::*; - -/// Represents a macro invocation. The Path indicates which macro -/// is being invoked, and the vector of token-trees contains the source -/// of the macro invocation. -/// -/// NB: the additional ident for a `macro_rules`-style macro is actually -/// stored in the enclosing item. Oog. -#[derive(Debug, Clone, Eq, PartialEq, Hash)] -pub struct Mac { - pub path: Path, - pub tts: Vec, -} - -/// When the main rust parser encounters a syntax-extension invocation, it -/// parses the arguments to the invocation as a token-tree. This is a very -/// loose structure, such that all sorts of different AST-fragments can -/// be passed to syntax extensions using a uniform type. -/// -/// If the syntax extension is an MBE macro, it will attempt to match its -/// LHS token tree against the provided token tree, and if it finds a -/// match, will transcribe the RHS token tree, splicing in any captured -/// `macro_parser::matched_nonterminals` into the `SubstNt`s it finds. -/// -/// The RHS of an MBE macro is the only place `SubstNt`s are substituted. -/// Nothing special happens to misnamed or misplaced `SubstNt`s. -#[derive(Debug, Clone, Eq, PartialEq, Hash)] -pub enum TokenTree { - /// A single token - Token(Token), - /// A delimited sequence of token trees - Delimited(Delimited), -} - -#[derive(Debug, Clone, Eq, PartialEq, Hash)] -pub struct Delimited { - /// The type of delimiter - pub delim: DelimToken, - /// The delimited sequence of token trees - pub tts: Vec, -} - -#[derive(Debug, Clone, Eq, PartialEq, Hash)] -pub enum Token { - // Expression-operator symbols. - Eq, - Lt, - Le, - EqEq, - Ne, - Ge, - Gt, - AndAnd, - OrOr, - Not, - Tilde, - BinOp(BinOpToken), - BinOpEq(BinOpToken), - - // Structural symbols - At, - Dot, - DotDot, - DotDotDot, - Comma, - Semi, - Colon, - ModSep, - RArrow, - LArrow, - FatArrow, - Pound, - Dollar, - Question, - - // Literals - Literal(Lit), - - // Name components - Ident(Ident), - Underscore, - Lifetime(Ident), - - DocComment(String), -} - -#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] -pub enum BinOpToken { - Plus, - Minus, - Star, - Slash, - Percent, - Caret, - And, - Or, - Shl, - Shr, -} - -/// A delimiter token -#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] -pub enum DelimToken { - /// A round parenthesis: `(` or `)` - Paren, - /// A square bracket: `[` or `]` - Bracket, - /// A curly brace: `{` or `}` - Brace, -} - -#[cfg(feature = "parsing")] -pub mod parsing { - use super::*; - use Lifetime; - use generics::parsing::lifetime; - use ident::parsing::{ident, word}; - use lit::parsing::lit; - use space::{block_comment, whitespace}; - - named!(pub mac -> Mac, do_parse!( - name: ident >> - punct!("!") >> - body: delimited >> - (Mac { - path: name.into(), - tts: vec![TokenTree::Delimited(body)], - }) - )); - - named!(pub token_trees -> Vec, many0!(token_tree)); - - named!(pub delimited -> Delimited, alt!( - delimited!( - punct!("("), - token_trees, - punct!(")") - ) => { |tts| Delimited { delim: DelimToken::Paren, tts: tts } } - | - delimited!( - punct!("["), - token_trees, - punct!("]") - ) => { |tts| Delimited { delim: DelimToken::Bracket, tts: tts } } - | - delimited!( - punct!("{"), - token_trees, - punct!("}") - ) => { |tts| Delimited { delim: DelimToken::Brace, tts: tts } } - )); - - named!(token_tree -> TokenTree, alt!( - map!(token, TokenTree::Token) - | - map!(delimited, TokenTree::Delimited) - )); - - named!(token -> Token, alt!( - keyword!("_") => { |_| Token::Underscore } - | - punct!("&&") => { |_| Token::AndAnd } // must be before BinOp - | - punct!("||") => { |_| Token::OrOr } // must be before BinOp - | - punct!("->") => { |_| Token::RArrow } // must be before BinOp - | - punct!("<-") => { |_| Token::LArrow } // must be before Lt - | - punct!("=>") => { |_| Token::FatArrow } // must be before Eq - | - punct!("...") => { |_| Token::DotDotDot } // must be before DotDot - | - punct!("..") => { |_| Token::DotDot } // must be before Dot - | - punct!(".") => { |_| Token::Dot } - | - map!(doc_comment, Token::DocComment) // must be before bin_op - | - map!(bin_op_eq, Token::BinOpEq) // must be before bin_op - | - map!(bin_op, Token::BinOp) - | - map!(lit, Token::Literal) - | - map!(word, Token::Ident) - | - map!(lifetime, |lt: Lifetime| Token::Lifetime(lt.ident)) - | - punct!("<=") => { |_| Token::Le } - | - punct!("==") => { |_| Token::EqEq } - | - punct!("!=") => { |_| Token::Ne } - | - punct!(">=") => { |_| Token::Ge } - | - punct!("::") => { |_| Token::ModSep } - | - punct!("=") => { |_| Token::Eq } - | - punct!("<") => { |_| Token::Lt } - | - punct!(">") => { |_| Token::Gt } - | - punct!("!") => { |_| Token::Not } - | - punct!("~") => { |_| Token::Tilde } - | - punct!("@") => { |_| Token::At } - | - punct!(",") => { |_| Token::Comma } - | - punct!(";") => { |_| Token::Semi } - | - punct!(":") => { |_| Token::Colon } - | - punct!("#") => { |_| Token::Pound } - | - punct!("$") => { |_| Token::Dollar } - | - punct!("?") => { |_| Token::Question } - )); - - named!(bin_op -> BinOpToken, alt!( - punct!("+") => { |_| BinOpToken::Plus } - | - punct!("-") => { |_| BinOpToken::Minus } - | - punct!("*") => { |_| BinOpToken::Star } - | - punct!("/") => { |_| BinOpToken::Slash } - | - punct!("%") => { |_| BinOpToken::Percent } - | - punct!("^") => { |_| BinOpToken::Caret } - | - punct!("&") => { |_| BinOpToken::And } - | - punct!("|") => { |_| BinOpToken::Or } - | - punct!("<<") => { |_| BinOpToken::Shl } - | - punct!(">>") => { |_| BinOpToken::Shr } - )); - - named!(bin_op_eq -> BinOpToken, alt!( - punct!("+=") => { |_| BinOpToken::Plus } - | - punct!("-=") => { |_| BinOpToken::Minus } - | - punct!("*=") => { |_| BinOpToken::Star } - | - punct!("/=") => { |_| BinOpToken::Slash } - | - punct!("%=") => { |_| BinOpToken::Percent } - | - punct!("^=") => { |_| BinOpToken::Caret } - | - punct!("&=") => { |_| BinOpToken::And } - | - punct!("|=") => { |_| BinOpToken::Or } - | - punct!("<<=") => { |_| BinOpToken::Shl } - | - punct!(">>=") => { |_| BinOpToken::Shr } - )); - - named!(doc_comment -> String, alt!( - do_parse!( - punct!("//!") >> - content: take_until!("\n") >> - (format!("//!{}", content)) - ) - | - do_parse!( - option!(whitespace) >> - peek!(tag!("/*!")) >> - com: block_comment >> - (com.to_owned()) - ) - | - do_parse!( - punct!("///") >> - not!(peek!(tag!("/"))) >> - content: take_until!("\n") >> - (format!("///{}", content)) - ) - | - do_parse!( - option!(whitespace) >> - peek!(tuple!(tag!("/**"), not!(tag!("*")))) >> - com: block_comment >> - (com.to_owned()) - ) - )); -} - -#[cfg(feature = "printing")] -mod printing { - use super::*; - use quote::{Tokens, ToTokens}; - - impl ToTokens for Mac { - fn to_tokens(&self, tokens: &mut Tokens) { - self.path.to_tokens(tokens); - tokens.append("!"); - for tt in &self.tts { - tt.to_tokens(tokens); - } - } - } - - impl ToTokens for TokenTree { - fn to_tokens(&self, tokens: &mut Tokens) { - match *self { - TokenTree::Token(ref token) => token.to_tokens(tokens), - TokenTree::Delimited(ref delimited) => delimited.to_tokens(tokens), - } - } - } - - impl DelimToken { - fn open(&self) -> &'static str { - match *self { - DelimToken::Paren => "(", - DelimToken::Bracket => "[", - DelimToken::Brace => "{", - } - } - - fn close(&self) -> &'static str { - match *self { - DelimToken::Paren => ")", - DelimToken::Bracket => "]", - DelimToken::Brace => "}", - } - } - } - - impl ToTokens for Delimited { - fn to_tokens(&self, tokens: &mut Tokens) { - tokens.append(self.delim.open()); - for tt in &self.tts { - tt.to_tokens(tokens); - } - tokens.append(self.delim.close()); - } - } - - impl ToTokens for Token { - fn to_tokens(&self, tokens: &mut Tokens) { - match *self { - Token::Eq => tokens.append("="), - Token::Lt => tokens.append("<"), - Token::Le => tokens.append("<="), - Token::EqEq => tokens.append("=="), - Token::Ne => tokens.append("!="), - Token::Ge => tokens.append(">="), - Token::Gt => tokens.append(">"), - Token::AndAnd => tokens.append("&&"), - Token::OrOr => tokens.append("||"), - Token::Not => tokens.append("!"), - Token::Tilde => tokens.append("~"), - Token::BinOp(binop) => tokens.append(binop.op()), - Token::BinOpEq(binop) => tokens.append(binop.assign_op()), - Token::At => tokens.append("@"), - Token::Dot => tokens.append("."), - Token::DotDot => tokens.append(".."), - Token::DotDotDot => tokens.append("..."), - Token::Comma => tokens.append(","), - Token::Semi => tokens.append(";"), - Token::Colon => tokens.append(":"), - Token::ModSep => tokens.append("::"), - Token::RArrow => tokens.append("->"), - Token::LArrow => tokens.append("<-"), - Token::FatArrow => tokens.append("=>"), - Token::Pound => tokens.append("#"), - Token::Dollar => tokens.append("$"), - Token::Question => tokens.append("?"), - Token::Literal(ref lit) => lit.to_tokens(tokens), - Token::Ident(ref ident) | - Token::Lifetime(ref ident) => ident.to_tokens(tokens), - Token::Underscore => tokens.append("_"), - Token::DocComment(ref com) => { - tokens.append(&format!("{}\n", com)); - } - } - } - } - - impl BinOpToken { - fn op(&self) -> &'static str { - match *self { - BinOpToken::Plus => "+", - BinOpToken::Minus => "-", - BinOpToken::Star => "*", - BinOpToken::Slash => "/", - BinOpToken::Percent => "%", - BinOpToken::Caret => "^", - BinOpToken::And => "&", - BinOpToken::Or => "|", - BinOpToken::Shl => "<<", - BinOpToken::Shr => ">>", - } - } - - fn assign_op(&self) -> &'static str { - match *self { - BinOpToken::Plus => "+=", - BinOpToken::Minus => "-=", - BinOpToken::Star => "*=", - BinOpToken::Slash => "/=", - BinOpToken::Percent => "%=", - BinOpToken::Caret => "^=", - BinOpToken::And => "&=", - BinOpToken::Or => "|=", - BinOpToken::Shl => "<<=", - BinOpToken::Shr => ">>=", - } - } - } - - impl ToTokens for BinOpToken { - fn to_tokens(&self, tokens: &mut Tokens) { - tokens.append(self.op()); - } - } -} diff --git a/third_party/rust/syn-0.10.8/src/macro_input.rs b/third_party/rust/syn-0.10.8/src/macro_input.rs deleted file mode 100644 index de99f27067db..000000000000 --- a/third_party/rust/syn-0.10.8/src/macro_input.rs +++ /dev/null @@ -1,110 +0,0 @@ -use super::*; - -#[derive(Debug, Clone, Eq, PartialEq, Hash)] -pub struct MacroInput { - pub ident: Ident, - pub vis: Visibility, - pub attrs: Vec, - pub generics: Generics, - pub body: Body, -} - -#[derive(Debug, Clone, Eq, PartialEq, Hash)] -pub enum Body { - Enum(Vec), - Struct(VariantData), -} - -#[cfg(feature = "parsing")] -pub mod parsing { - use super::*; - use Generics; - use attr::parsing::outer_attr; - use data::parsing::{visibility, struct_body, enum_body}; - use generics::parsing::generics; - use ident::parsing::ident; - - named!(pub macro_input -> MacroInput, do_parse!( - attrs: many0!(outer_attr) >> - vis: visibility >> - which: alt!(keyword!("struct") | keyword!("enum")) >> - id: ident >> - generics: generics >> - item: switch!(value!(which), - "struct" => map!(struct_body, move |(wh, body)| MacroInput { - ident: id, - vis: vis, - attrs: attrs, - generics: Generics { - where_clause: wh, - .. generics - }, - body: Body::Struct(body), - }) - | - "enum" => map!(enum_body, move |(wh, body)| MacroInput { - ident: id, - vis: vis, - attrs: attrs, - generics: Generics { - where_clause: wh, - .. generics - }, - body: Body::Enum(body), - }) - ) >> - (item) - )); -} - -#[cfg(feature = "printing")] -mod printing { - use super::*; - use attr::FilterAttrs; - use data::VariantData; - use quote::{Tokens, ToTokens}; - - impl ToTokens for MacroInput { - fn to_tokens(&self, tokens: &mut Tokens) { - for attr in self.attrs.outer() { - attr.to_tokens(tokens); - } - self.vis.to_tokens(tokens); - match self.body { - Body::Enum(_) => tokens.append("enum"), - Body::Struct(_) => tokens.append("struct"), - } - self.ident.to_tokens(tokens); - self.generics.to_tokens(tokens); - match self.body { - Body::Enum(ref variants) => { - self.generics.where_clause.to_tokens(tokens); - tokens.append("{"); - for variant in variants { - variant.to_tokens(tokens); - tokens.append(","); - } - tokens.append("}"); - } - Body::Struct(ref variant_data) => { - match *variant_data { - VariantData::Struct(_) => { - self.generics.where_clause.to_tokens(tokens); - variant_data.to_tokens(tokens); - // no semicolon - } - VariantData::Tuple(_) => { - variant_data.to_tokens(tokens); - self.generics.where_clause.to_tokens(tokens); - tokens.append(";"); - } - VariantData::Unit => { - self.generics.where_clause.to_tokens(tokens); - tokens.append(";"); - } - } - } - } - } - } -} diff --git a/third_party/rust/syn-0.10.8/src/nom.rs b/third_party/rust/syn-0.10.8/src/nom.rs deleted file mode 100644 index 599a4bc537ce..000000000000 --- a/third_party/rust/syn-0.10.8/src/nom.rs +++ /dev/null @@ -1,505 +0,0 @@ -// Adapted from nom by removing the -// IResult::Incomplete variant, which we don't use and which unfortunately more -// than doubles the compilation time. - -#[derive(Debug, PartialEq, Eq, Clone)] -pub enum IResult { - /// indicates a correct parsing, the first field containing the rest of the - /// unparsed data, the second field contains the parsed data - Done(I, O), - Error, -} - -macro_rules! named { - ($name:ident -> $o:ty, $submac:ident!( $($args:tt)* )) => { - fn $name(i: &str) -> $crate::nom::IResult<&str, $o> { - $submac!(i, $($args)*) - } - }; - - (pub $name:ident -> $o:ty, $submac:ident!( $($args:tt)* )) => { - pub fn $name(i: &str) -> $crate::nom::IResult<&str, $o> { - $submac!(i, $($args)*) - } - }; -} - -macro_rules! call { - ($i:expr, $fun:expr $(, $args:expr)*) => { - $fun($i $(, $args)*) - }; -} - -macro_rules! map { - ($i:expr, $submac:ident!( $($args:tt)* ), $g:expr) => { - map_impl!($i, $submac!($($args)*), call!($g)) - }; - - ($i:expr, $f:expr, $g:expr) => { - map_impl!($i, call!($f), call!($g)) - }; -} - -/// Internal parser, do not use directly -macro_rules! map_impl { - ($i:expr, $submac:ident!( $($args:tt)* ), $submac2:ident!( $($args2:tt)* )) => { - match $submac!($i, $($args)*) { - $crate::nom::IResult::Error => $crate::nom::IResult::Error, - $crate::nom::IResult::Done(i, o) => { - $crate::nom::IResult::Done(i, $submac2!(o, $($args2)*)) - } - } - }; -} - -macro_rules! not { - ($i:expr, $submac:ident!( $($args:tt)* )) => { - match $submac!($i, $($args)*) { - $crate::nom::IResult::Done(_, _) => $crate::nom::IResult::Error, - $crate::nom::IResult::Error => $crate::nom::IResult::Done($i, ""), - } - }; -} - -// This is actually nom's cond_with_error. -macro_rules! cond { - ($i:expr, $cond:expr, $submac:ident!( $($args:tt)* )) => { - if $cond { - match $submac!($i, $($args)*) { - $crate::nom::IResult::Done(i, o) => $crate::nom::IResult::Done(i, ::std::option::Option::Some(o)), - $crate::nom::IResult::Error => $crate::nom::IResult::Error, - } - } else { - $crate::nom::IResult::Done($i, ::std::option::Option::None) - } - }; - - ($i:expr, $cond:expr, $f:expr) => { - cond!($i, $cond, call!($f)) - }; -} - -macro_rules! cond_reduce { - ($i:expr, $cond:expr, $submac:ident!( $($args:tt)* )) => { - if $cond { - $submac!($i, $($args)*) - } else { - $crate::nom::IResult::Error - } - }; - - ($i:expr, $cond:expr, $f:expr) => { - cond_reduce!($i, $cond, call!($f)) - }; -} - -macro_rules! preceded { - ($i:expr, $submac:ident!( $($args:tt)* ), $submac2:ident!( $($args2:tt)* )) => { - match tuple!($i, $submac!($($args)*), $submac2!($($args2)*)) { - $crate::nom::IResult::Done(remaining, (_, o)) => $crate::nom::IResult::Done(remaining, o), - $crate::nom::IResult::Error => $crate::nom::IResult::Error, - } - }; - - ($i:expr, $submac:ident!( $($args:tt)* ), $g:expr) => { - preceded!($i, $submac!($($args)*), call!($g)) - }; - - ($i:expr, $f:expr, $submac:ident!( $($args:tt)* )) => { - preceded!($i, call!($f), $submac!($($args)*)) - }; - - ($i:expr, $f:expr, $g:expr) => { - preceded!($i, call!($f), call!($g)) - }; -} - -macro_rules! terminated { - ($i:expr, $submac:ident!( $($args:tt)* ), $submac2:ident!( $($args2:tt)* )) => { - match tuple!($i, $submac!($($args)*), $submac2!($($args2)*)) { - $crate::nom::IResult::Done(remaining, (o, _)) => $crate::nom::IResult::Done(remaining, o), - $crate::nom::IResult::Error => $crate::nom::IResult::Error, - } - }; - - ($i:expr, $submac:ident!( $($args:tt)* ), $g:expr) => { - terminated!($i, $submac!($($args)*), call!($g)) - }; - - ($i:expr, $f:expr, $submac:ident!( $($args:tt)* )) => { - terminated!($i, call!($f), $submac!($($args)*)) - }; - - ($i:expr, $f:expr, $g:expr) => { - terminated!($i, call!($f), call!($g)) - }; -} - -macro_rules! many0 { - ($i:expr, $submac:ident!( $($args:tt)* )) => {{ - let ret; - let mut res = ::std::vec::Vec::new(); - let mut input = $i; - - loop { - if input.is_empty() { - ret = $crate::nom::IResult::Done(input, res); - break; - } - - match $submac!(input, $($args)*) { - $crate::nom::IResult::Error => { - ret = $crate::nom::IResult::Done(input, res); - break; - } - $crate::nom::IResult::Done(i, o) => { - // loop trip must always consume (otherwise infinite loops) - if i.len() == input.len() { - ret = $crate::nom::IResult::Error; - break; - } - - res.push(o); - input = i; - } - } - } - - ret - }}; - - ($i:expr, $f:expr) => { - $crate::nom::many0($i, $f) - }; -} - -pub fn many0<'a, T>(mut input: &'a str, - f: fn(&'a str) -> IResult<&'a str, T>) - -> IResult<&'a str, Vec> { - let mut res = Vec::new(); - - loop { - if input.is_empty() { - return IResult::Done(input, res); - } - - match f(input) { - IResult::Error => { - return IResult::Done(input, res); - } - IResult::Done(i, o) => { - // loop trip must always consume (otherwise infinite loops) - if i.len() == input.len() { - return IResult::Error; - } - - res.push(o); - input = i; - } - } - } -} - -macro_rules! peek { - ($i:expr, $submac:ident!( $($args:tt)* )) => { - match $submac!($i, $($args)*) { - $crate::nom::IResult::Done(_, o) => $crate::nom::IResult::Done($i, o), - $crate::nom::IResult::Error => $crate::nom::IResult::Error, - } - }; -} - -macro_rules! take_while1 { - ($input:expr, $submac:ident!( $($args:tt)* )) => {{ - let mut offset = $input.len(); - for (o, c) in $input.char_indices() { - if !$submac!(c, $($args)*) { - offset = o; - break; - } - } - if offset == 0 { - $crate::nom::IResult::Error - } else if offset < $input.len() { - $crate::nom::IResult::Done(&$input[offset..], &$input[..offset]) - } else { - $crate::nom::IResult::Done("", $input) - } - }}; - - ($input:expr, $f:expr) => { - take_while1!($input, call!($f)); - }; -} - -pub fn str_chars(s: &str) -> Vec { - // Can't do `s.chars().collect()` because it triggers a compiler bug in 1.12.0 - // https://github.com/dtolnay/syn/issues/20 - let mut result = Vec::new(); - for ch in s.chars() { - result.push(ch); - } - result -} - -macro_rules! take_until { - ($input:expr, $substr:expr) => {{ - if $substr.len() > $input.len() { - $crate::nom::IResult::Error - } else { - let substr_vec: Vec = $crate::nom::str_chars($substr); - let mut window: Vec = vec![]; - let mut offset = $input.len(); - let mut parsed = false; - for (o, c) in $input.char_indices() { - window.push(c); - if window.len() > substr_vec.len() { - window.remove(0); - } - if window == substr_vec { - parsed = true; - window.pop(); - let window_len: usize = window.iter() - .map(|x| x.len_utf8()) - .fold(0, |x, y| x + y); - offset = o - window_len; - break; - } - } - if parsed { - $crate::nom::IResult::Done(&$input[offset..], &$input[..offset]) - } else { - $crate::nom::IResult::Error - } - } - }}; -} - -macro_rules! tag { - ($i:expr, $tag: expr) => { - if $i.starts_with($tag) { - $crate::nom::IResult::Done(&$i[$tag.len()..], &$i[0..$tag.len()]) - } else { - $crate::nom::IResult::Error - } - }; -} - -macro_rules! switch { - ($i:expr, $submac:ident!( $($args:tt)* ), $($p:pat => $subrule:ident!( $($args2:tt)* ))|* ) => { - match $submac!($i, $($args)*) { - $crate::nom::IResult::Error => $crate::nom::IResult::Error, - $crate::nom::IResult::Done(i, o) => match o { - $( - $p => $subrule!(i, $($args2)*), - )* - _ => $crate::nom::IResult::Error, - } - } - }; -} - -macro_rules! value { - ($i:expr, $res:expr) => { - $crate::nom::IResult::Done($i, $res) - }; -} - -macro_rules! delimited { - ($i:expr, $submac:ident!( $($args:tt)* ), $($rest:tt)+) => { - match tuple_parser!($i, (), $submac!($($args)*), $($rest)*) { - $crate::nom::IResult::Error => $crate::nom::IResult::Error, - $crate::nom::IResult::Done(i1, (_, o, _)) => $crate::nom::IResult::Done(i1, o) - } - }; - - ($i:expr, $f:expr, $($rest:tt)+) => { - delimited!($i, call!($f), $($rest)*) - }; -} - -macro_rules! separated_nonempty_list { - ($i:expr, $sep:ident!( $($args:tt)* ), $submac:ident!( $($args2:tt)* )) => {{ - let mut res = ::std::vec::Vec::new(); - let mut input = $i; - - // get the first element - match $submac!(input, $($args2)*) { - $crate::nom::IResult::Error => $crate::nom::IResult::Error, - $crate::nom::IResult::Done(i, o) => { - if i.len() == input.len() { - $crate::nom::IResult::Error - } else { - res.push(o); - input = i; - - while let $crate::nom::IResult::Done(i2, _) = $sep!(input, $($args)*) { - if i2.len() == input.len() { - break; - } - - if let $crate::nom::IResult::Done(i3, o3) = $submac!(i2, $($args2)*) { - if i3.len() == i2.len() { - break; - } - res.push(o3); - input = i3; - } else { - break; - } - } - $crate::nom::IResult::Done(input, res) - } - } - } - }}; - - ($i:expr, $submac:ident!( $($args:tt)* ), $g:expr) => { - separated_nonempty_list!($i, $submac!($($args)*), call!($g)) - }; - - ($i:expr, $f:expr, $submac:ident!( $($args:tt)* )) => { - separated_nonempty_list!($i, call!($f), $submac!($($args)*)) - }; - - ($i:expr, $f:expr, $g:expr) => { - separated_nonempty_list!($i, call!($f), call!($g)) - }; -} - -macro_rules! tuple { - ($i:expr, $($rest:tt)*) => { - tuple_parser!($i, (), $($rest)*) - }; -} - -/// Internal parser, do not use directly -macro_rules! tuple_parser { - ($i:expr, ($($parsed:tt),*), $e:ident, $($rest:tt)*) => { - tuple_parser!($i, ($($parsed),*), call!($e), $($rest)*) - }; - - ($i:expr, (), $submac:ident!( $($args:tt)* ), $($rest:tt)*) => { - match $submac!($i, $($args)*) { - $crate::nom::IResult::Error => $crate::nom::IResult::Error, - $crate::nom::IResult::Done(i, o) => - tuple_parser!(i, (o), $($rest)*), - } - }; - - ($i:expr, ($($parsed:tt)*), $submac:ident!( $($args:tt)* ), $($rest:tt)*) => { - match $submac!($i, $($args)*) { - $crate::nom::IResult::Error => $crate::nom::IResult::Error, - $crate::nom::IResult::Done(i, o) => - tuple_parser!(i, ($($parsed)* , o), $($rest)*), - } - }; - - ($i:expr, ($($parsed:tt),*), $e:ident) => { - tuple_parser!($i, ($($parsed),*), call!($e)) - }; - - ($i:expr, (), $submac:ident!( $($args:tt)* )) => { - $submac!($i, $($args)*) - }; - - ($i:expr, ($($parsed:expr),*), $submac:ident!( $($args:tt)* )) => { - match $submac!($i, $($args)*) { - $crate::nom::IResult::Error => $crate::nom::IResult::Error, - $crate::nom::IResult::Done(i, o) => $crate::nom::IResult::Done(i, ($($parsed),*, o)) - } - }; - - ($i:expr, ($($parsed:expr),*)) => { - $crate::nom::IResult::Done($i, ($($parsed),*)) - }; -} - -macro_rules! alt { - ($i:expr, $e:ident | $($rest:tt)*) => { - alt!($i, call!($e) | $($rest)*) - }; - - ($i:expr, $subrule:ident!( $($args:tt)*) | $($rest:tt)*) => { - match $subrule!($i, $($args)*) { - res @ $crate::nom::IResult::Done(_, _) => res, - _ => alt!($i, $($rest)*) - } - }; - - ($i:expr, $subrule:ident!( $($args:tt)* ) => { $gen:expr } | $($rest:tt)+) => { - match $subrule!($i, $($args)*) { - $crate::nom::IResult::Done(i, o) => $crate::nom::IResult::Done(i, $gen(o)), - $crate::nom::IResult::Error => alt!($i, $($rest)*) - } - }; - - ($i:expr, $e:ident => { $gen:expr } | $($rest:tt)*) => { - alt!($i, call!($e) => { $gen } | $($rest)*) - }; - - ($i:expr, $e:ident => { $gen:expr }) => { - alt!($i, call!($e) => { $gen }) - }; - - ($i:expr, $subrule:ident!( $($args:tt)* ) => { $gen:expr }) => { - match $subrule!($i, $($args)*) { - $crate::nom::IResult::Done(i, o) => $crate::nom::IResult::Done(i, $gen(o)), - $crate::nom::IResult::Error => $crate::nom::IResult::Error, - } - }; - - ($i:expr, $e:ident) => { - alt!($i, call!($e)) - }; - - ($i:expr, $subrule:ident!( $($args:tt)*)) => { - $subrule!($i, $($args)*) - }; -} - -macro_rules! do_parse { - ($i:expr, ( $($rest:expr),* )) => { - $crate::nom::IResult::Done($i, ( $($rest),* )) - }; - - ($i:expr, $e:ident >> $($rest:tt)*) => { - do_parse!($i, call!($e) >> $($rest)*) - }; - - ($i:expr, $submac:ident!( $($args:tt)* ) >> $($rest:tt)*) => { - match $submac!($i, $($args)*) { - $crate::nom::IResult::Error => $crate::nom::IResult::Error, - $crate::nom::IResult::Done(i, _) => - do_parse!(i, $($rest)*), - } - }; - - ($i:expr, $field:ident : $e:ident >> $($rest:tt)*) => { - do_parse!($i, $field: call!($e) >> $($rest)*) - }; - - ($i:expr, $field:ident : $submac:ident!( $($args:tt)* ) >> $($rest:tt)*) => { - match $submac!($i, $($args)*) { - $crate::nom::IResult::Error => $crate::nom::IResult::Error, - $crate::nom::IResult::Done(i, o) => { - let $field = o; - do_parse!(i, $($rest)*) - }, - } - }; - - ($i:expr, mut $field:ident : $e:ident >> $($rest:tt)*) => { - do_parse!($i, mut $field: call!($e) >> $($rest)*) - }; - - ($i:expr, mut $field:ident : $submac:ident!( $($args:tt)* ) >> $($rest:tt)*) => { - match $submac!($i, $($args)*) { - $crate::nom::IResult::Error => $crate::nom::IResult::Error, - $crate::nom::IResult::Done(i, o) => { - let mut $field = o; - do_parse!(i, $($rest)*) - }, - } - }; -} diff --git a/third_party/rust/syn-0.10.8/src/op.rs b/third_party/rust/syn-0.10.8/src/op.rs deleted file mode 100644 index d4b0bc7f2a3d..000000000000 --- a/third_party/rust/syn-0.10.8/src/op.rs +++ /dev/null @@ -1,192 +0,0 @@ -#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] -pub enum BinOp { - /// The `+` operator (addition) - Add, - /// The `-` operator (subtraction) - Sub, - /// The `*` operator (multiplication) - Mul, - /// The `/` operator (division) - Div, - /// The `%` operator (modulus) - Rem, - /// The `&&` operator (logical and) - And, - /// The `||` operator (logical or) - Or, - /// The `^` operator (bitwise xor) - BitXor, - /// The `&` operator (bitwise and) - BitAnd, - /// The `|` operator (bitwise or) - BitOr, - /// The `<<` operator (shift left) - Shl, - /// The `>>` operator (shift right) - Shr, - /// The `==` operator (equality) - Eq, - /// The `<` operator (less than) - Lt, - /// The `<=` operator (less than or equal to) - Le, - /// The `!=` operator (not equal to) - Ne, - /// The `>=` operator (greater than or equal to) - Ge, - /// The `>` operator (greater than) - Gt, -} - -#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] -pub enum UnOp { - /// The `*` operator for dereferencing - Deref, - /// The `!` operator for logical inversion - Not, - /// The `-` operator for negation - Neg, -} - -#[cfg(feature = "parsing")] -pub mod parsing { - use super::*; - - named!(pub binop -> BinOp, alt!( - punct!("&&") => { |_| BinOp::And } - | - punct!("||") => { |_| BinOp::Or } - | - punct!("<<") => { |_| BinOp::Shl } - | - punct!(">>") => { |_| BinOp::Shr } - | - punct!("==") => { |_| BinOp::Eq } - | - punct!("<=") => { |_| BinOp::Le } - | - punct!("!=") => { |_| BinOp::Ne } - | - punct!(">=") => { |_| BinOp::Ge } - | - punct!("+") => { |_| BinOp::Add } - | - punct!("-") => { |_| BinOp::Sub } - | - punct!("*") => { |_| BinOp::Mul } - | - punct!("/") => { |_| BinOp::Div } - | - punct!("%") => { |_| BinOp::Rem } - | - punct!("^") => { |_| BinOp::BitXor } - | - punct!("&") => { |_| BinOp::BitAnd } - | - punct!("|") => { |_| BinOp::BitOr } - | - punct!("<") => { |_| BinOp::Lt } - | - punct!(">") => { |_| BinOp::Gt } - )); - - #[cfg(feature = "full")] - named!(pub assign_op -> BinOp, alt!( - punct!("+=") => { |_| BinOp::Add } - | - punct!("-=") => { |_| BinOp::Sub } - | - punct!("*=") => { |_| BinOp::Mul } - | - punct!("/=") => { |_| BinOp::Div } - | - punct!("%=") => { |_| BinOp::Rem } - | - punct!("^=") => { |_| BinOp::BitXor } - | - punct!("&=") => { |_| BinOp::BitAnd } - | - punct!("|=") => { |_| BinOp::BitOr } - | - punct!("<<=") => { |_| BinOp::Shl } - | - punct!(">>=") => { |_| BinOp::Shr } - )); - - named!(pub unop -> UnOp, alt!( - punct!("*") => { |_| UnOp::Deref } - | - punct!("!") => { |_| UnOp::Not } - | - punct!("-") => { |_| UnOp::Neg } - )); -} - -#[cfg(feature = "printing")] -mod printing { - use super::*; - use quote::{Tokens, ToTokens}; - - impl BinOp { - pub fn op(&self) -> &'static str { - match *self { - BinOp::Add => "+", - BinOp::Sub => "-", - BinOp::Mul => "*", - BinOp::Div => "/", - BinOp::Rem => "%", - BinOp::And => "&&", - BinOp::Or => "||", - BinOp::BitXor => "^", - BinOp::BitAnd => "&", - BinOp::BitOr => "|", - BinOp::Shl => "<<", - BinOp::Shr => ">>", - BinOp::Eq => "==", - BinOp::Lt => "<", - BinOp::Le => "<=", - BinOp::Ne => "!=", - BinOp::Ge => ">=", - BinOp::Gt => ">", - } - } - - pub fn assign_op(&self) -> Option<&'static str> { - match *self { - BinOp::Add => Some("+="), - BinOp::Sub => Some("-="), - BinOp::Mul => Some("*="), - BinOp::Div => Some("/="), - BinOp::Rem => Some("%="), - BinOp::BitXor => Some("^="), - BinOp::BitAnd => Some("&="), - BinOp::BitOr => Some("|="), - BinOp::Shl => Some("<<="), - BinOp::Shr => Some(">>="), - _ => None, - } - } - } - - impl ToTokens for BinOp { - fn to_tokens(&self, tokens: &mut Tokens) { - tokens.append(self.op()); - } - } - - impl UnOp { - pub fn op(&self) -> &'static str { - match *self { - UnOp::Deref => "*", - UnOp::Not => "!", - UnOp::Neg => "-", - } - } - } - - impl ToTokens for UnOp { - fn to_tokens(&self, tokens: &mut Tokens) { - tokens.append(self.op()); - } - } -} diff --git a/third_party/rust/syn-0.10.8/src/registry.rs b/third_party/rust/syn-0.10.8/src/registry.rs deleted file mode 100644 index 24e1c6b1c087..000000000000 --- a/third_party/rust/syn-0.10.8/src/registry.rs +++ /dev/null @@ -1,392 +0,0 @@ -use super::{Attribute, AttrStyle, Body, Crate, Ident, Item, ItemKind, MacroInput, MetaItem, - NestedMetaItem}; -use quote::Tokens; - -use std::collections::BTreeMap as Map; -use std::fs::File; -use std::io::{Read, Write}; -use std::path::Path; - -/// Implementation of a custom derive. Custom derives take a struct or enum and -/// expand it into zero or more items, typically `impl` items. -pub trait CustomDerive { - /// Expand the given struct or enum. If this custom derive modifies the - /// input item or preserves it unmodified, it must be returned back in the - /// `original` field of Expanded. The custom derive may discard the input - /// item by setting `original` to None. - fn expand(&self, input: MacroInput) -> Result; -} - -/// Produced by expanding a custom derive. -pub struct Expanded { - /// The items (typically `impl` items) constructed by the custom derive. - pub new_items: Vec, - /// The input to the custom derive, whether modified or unmodified. If the - /// custom derive discards the input item it may do so by setting `original` - /// to None. - pub original: Option, -} - -/// Registry of custom derives. Callers add custom derives to a registry, then -/// use the registry to expand those derives in a source file. -#[derive(Default)] -pub struct Registry<'a> { - derives: Map>, -} - -impl CustomDerive for T - where T: Fn(MacroInput) -> Result -{ - fn expand(&self, input: MacroInput) -> Result { - self(input) - } -} - -impl<'a> Registry<'a> { - pub fn new() -> Self { - Default::default() - } - - /// Register a custom derive. A `fn(MacroInput) -> Result` - /// may be used as a custom derive. - /// - /// ```ignore - /// registry.add_derive("Serialize", expand_serialize); - /// ``` - pub fn add_derive(&mut self, name: &str, derive: T) - where T: CustomDerive + 'a - { - self.derives.insert(name.into(), Box::new(derive)); - } - - /// Read Rust source code from the `src` file, expand the custom derives - /// that have been registered, and write the result to the `dst` file. - pub fn expand_file(&self, src: S, dst: D) -> Result<(), String> - where S: AsRef, - D: AsRef - { - // Open the src file - let mut src = match File::open(src) { - Ok(open) => open, - Err(err) => return Err(err.to_string()), - }; - - // Read the contents of the src file to a String - let mut content = String::new(); - if let Err(err) = src.read_to_string(&mut content) { - return Err(err.to_string()); - } - - // Parse the contents - let krate = try!(super::parse_crate(&content)); - - // Expand - let expanded = try!(expand_crate(self, krate)); - - // Print the expanded code to a String - let out = try!(pretty(quote!(#expanded))); - - // Create or truncate the dst file, opening in write-only mode - let mut dst = match File::create(dst) { - Ok(create) => create, - Err(err) => return Err(err.to_string()), - }; - - // Write expanded code to the dst file - if let Err(err) = dst.write_all(out.as_bytes()) { - return Err(err.to_string()); - } - - Ok(()) - } -} - -fn expand_crate(reg: &Registry, krate: Crate) -> Result { - let mut items = Vec::new(); - for item in krate.items { - try!(expand_item(reg, item, Vec::new(), &mut items)); - } - Ok(Crate { items: items, ..krate }) -} - -fn expand_item(reg: &Registry, - mut item: Item, - cfg: Vec, - out: &mut Vec) - -> Result<(), String> { - let (body, generics) = match item.node { - ItemKind::Enum(variants, generics) => (Body::Enum(variants), generics), - ItemKind::Struct(variant_data, generics) => (Body::Struct(variant_data), generics), - _ => { - // Custom derives cannot apply to this item, preserve it unmodified - item.attrs.extend(combine_cfgs(cfg)); - out.push(item); - return Ok(()); - } - }; - let macro_input = MacroInput { - ident: item.ident, - vis: item.vis, - attrs: item.attrs, - generics: generics, - body: body, - }; - expand_macro_input(reg, macro_input, cfg, out) -} - -fn expand_macro_input(reg: &Registry, - mut input: MacroInput, - inherited_cfg: Vec, - out: &mut Vec) - -> Result<(), String> { - let mut derives = Vec::new(); - let mut all_cfg = inherited_cfg; - - // Find custom derives on this item, removing them from the input - input.attrs = input.attrs - .into_iter() - .flat_map(|attr| { - let (new_derives, cfg, attr) = parse_attr(reg, attr); - derives.extend(new_derives); - all_cfg.extend(cfg); - attr - }) - .collect(); - - // Expand each custom derive - for derive in derives { - let expanded = try!(reg.derives[derive.name.as_ref()].expand(input)); - - for new_item in expanded.new_items { - let mut extended_cfg = all_cfg.clone(); - extended_cfg.extend(derive.cfg.clone()); - try!(expand_item(reg, new_item, extended_cfg, out)); - } - - input = match expanded.original { - Some(input) => input, - None => return Ok(()), - }; - } - - input.attrs.extend(combine_cfgs(all_cfg)); - out.push(input.into()); - Ok(()) -} - -struct Derive { - name: Ident, - /// If the custom derive was behind a cfg_attr - cfg: Option, -} - -/// Pull custom derives and cfgs out of the given Attribute. -fn parse_attr(reg: &Registry, - attr: Attribute) - -> (Vec, Vec, Option) { - if attr.style != AttrStyle::Outer || attr.is_sugared_doc { - return (Vec::new(), Vec::new(), Some(attr)); - } - - let (name, nested) = match attr.value { - MetaItem::List(name, nested) => (name, nested), - _ => return (Vec::new(), Vec::new(), Some(attr)), - }; - - match name.as_ref() { - "derive" => { - let (derives, attr) = parse_derive_attr(reg, nested); - let derives = derives.into_iter() - .map(|d| { - Derive { - name: d, - cfg: None, - } - }) - .collect(); - (derives, Vec::new(), attr) - } - "cfg_attr" => { - let (derives, attr) = parse_cfg_attr(reg, nested); - (derives, Vec::new(), attr) - } - "cfg" => (Vec::new(), nested, None), - _ => { - // Rebuild the original attribute because it was destructured above - let attr = Attribute { - style: AttrStyle::Outer, - value: MetaItem::List(name, nested), - is_sugared_doc: false, - }; - (Vec::new(), Vec::new(), Some(attr)) - } - } -} - -/// Assuming the given nested meta-items came from a #[derive(...)] attribute, -/// pull out the ones that are custom derives. -fn parse_derive_attr(reg: &Registry, - nested: Vec) - -> (Vec, Option) { - let mut derives = Vec::new(); - - let remaining: Vec<_> = nested.into_iter() - .flat_map(|meta| { - let word = match meta { - NestedMetaItem::MetaItem(MetaItem::Word(word)) => word, - _ => return Some(meta), - }; - if reg.derives.contains_key(word.as_ref()) { - derives.push(word); - None - } else { - Some(NestedMetaItem::MetaItem(MetaItem::Word(word))) - } - }) - .collect(); - - let attr = if remaining.is_empty() { - // Elide an empty #[derive()] - None - } else { - Some(Attribute { - style: AttrStyle::Outer, - value: MetaItem::List("derive".into(), remaining), - is_sugared_doc: false, - }) - }; - - (derives, attr) -} - -/// Assuming the given nested meta-items came from a #[cfg_attr(...)] attribute, -/// pull out any custom derives contained within. -fn parse_cfg_attr(reg: &Registry, nested: Vec) -> (Vec, Option) { - if nested.len() != 2 { - let attr = Attribute { - style: AttrStyle::Outer, - value: MetaItem::List("cfg_attr".into(), nested), - is_sugared_doc: false, - }; - return (Vec::new(), Some(attr)); - } - - let mut iter = nested.into_iter(); - let cfg = iter.next().unwrap(); - let arg = iter.next().unwrap(); - - let (name, nested) = match arg { - NestedMetaItem::MetaItem(MetaItem::List(name, nested)) => (name, nested), - _ => { - let attr = Attribute { - style: AttrStyle::Outer, - value: MetaItem::List("cfg_attr".into(), vec![cfg, arg]), - is_sugared_doc: false, - }; - return (Vec::new(), Some(attr)); - } - }; - - if name == "derive" { - let (derives, attr) = parse_derive_attr(reg, nested); - let derives = derives.into_iter() - .map(|d| { - Derive { - name: d, - cfg: Some(cfg.clone()), - } - }) - .collect(); - let attr = attr.map(|attr| { - Attribute { - style: AttrStyle::Outer, - value: MetaItem::List("cfg_attr".into(), - vec![cfg, NestedMetaItem::MetaItem(attr.value)]), - is_sugared_doc: false, - } - }); - (derives, attr) - } else { - let attr = Attribute { - style: AttrStyle::Outer, - value: - MetaItem::List("cfg_attr".into(), - vec![cfg, NestedMetaItem::MetaItem(MetaItem::List(name, nested))]), - is_sugared_doc: false, - }; - (Vec::new(), Some(attr)) - } -} - -/// Combine a list of cfg expressions into an attribute like `#[cfg(a)]` or -/// `#[cfg(all(a, b, c))]`, or nothing if there are no cfg expressions. -fn combine_cfgs(cfg: Vec) -> Option { - // Flatten `all` cfgs so we don't nest `all` inside of `all`. - let cfg: Vec<_> = cfg.into_iter() - .flat_map(|cfg| { - let (name, nested) = match cfg { - NestedMetaItem::MetaItem(MetaItem::List(name, nested)) => (name, nested), - _ => return vec![cfg], - }; - if name == "all" { - nested - } else { - vec![NestedMetaItem::MetaItem(MetaItem::List(name, nested))] - } - }) - .collect(); - - let value = match cfg.len() { - 0 => return None, - 1 => cfg, - _ => vec![NestedMetaItem::MetaItem(MetaItem::List("all".into(), cfg))], - }; - - Some(Attribute { - style: AttrStyle::Outer, - value: MetaItem::List("cfg".into(), value), - is_sugared_doc: false, - }) -} - -#[cfg(not(feature = "pretty"))] -fn pretty(tokens: Tokens) -> Result { - Ok(tokens.to_string()) -} - -#[cfg(feature = "pretty")] -fn pretty(tokens: Tokens) -> Result { - use syntax::parse::{self, ParseSess}; - use syntax::print::pprust; - - let name = "syn".to_string(); - let source = tokens.to_string(); - let sess = ParseSess::new(); - let krate = match parse::parse_crate_from_source_str(name, source, &sess) { - Ok(krate) => krate, - Err(mut err) => { - err.emit(); - return Err("pretty printer failed to parse expanded code".into()); - } - }; - - if sess.span_diagnostic.has_errors() { - return Err("pretty printer failed to parse expanded code".into()); - } - - let mut reader = &tokens.to_string().into_bytes()[..]; - let mut writer = Vec::new(); - let ann = pprust::NoAnn; - - try!(pprust::print_crate( - sess.codemap(), - &sess.span_diagnostic, - &krate, - "".to_string(), - &mut reader, - Box::new(&mut writer), - &ann, - false).map_err(|err| err.to_string())); - - String::from_utf8(writer).map_err(|err| err.to_string()) -} diff --git a/third_party/rust/syn-0.10.8/src/space.rs b/third_party/rust/syn-0.10.8/src/space.rs deleted file mode 100644 index d168e135d3a3..000000000000 --- a/third_party/rust/syn-0.10.8/src/space.rs +++ /dev/null @@ -1,99 +0,0 @@ -use nom::IResult; -use unicode_xid::UnicodeXID; - -pub fn whitespace(input: &str) -> IResult<&str, ()> { - if input.is_empty() { - return IResult::Error; - } - - let bytes = input.as_bytes(); - let mut i = 0; - while i < bytes.len() { - let s = &input[i..]; - if bytes[i] == b'/' { - if s.starts_with("//") && (!s.starts_with("///") || s.starts_with("////")) && - !s.starts_with("//!") { - if let Some(len) = s.find('\n') { - i += len + 1; - continue; - } - break; - } else if s.starts_with("/*") && (!s.starts_with("/**") || s.starts_with("/***")) && - !s.starts_with("/*!") { - match block_comment(s) { - IResult::Done(_, com) => { - i += com.len(); - continue; - } - IResult::Error => { - return IResult::Error; - } - } - } - } - match bytes[i] { - b' ' | 0x09...0x0d => { - i += 1; - continue; - } - b if b <= 0x7f => {} - _ => { - let ch = s.chars().next().unwrap(); - if is_whitespace(ch) { - i += ch.len_utf8(); - continue; - } - } - } - return if i > 0 { - IResult::Done(s, ()) - } else { - IResult::Error - }; - } - IResult::Done("", ()) -} - -pub fn block_comment(input: &str) -> IResult<&str, &str> { - if !input.starts_with("/*") { - return IResult::Error; - } - - let mut depth = 0; - let bytes = input.as_bytes(); - let mut i = 0; - let upper = bytes.len() - 1; - while i < upper { - if bytes[i] == b'/' && bytes[i + 1] == b'*' { - depth += 1; - i += 1; // eat '*' - } else if bytes[i] == b'*' && bytes[i + 1] == b'/' { - depth -= 1; - if depth == 0 { - return IResult::Done(&input[i + 2..], &input[..i + 2]); - } - i += 1; // eat '/' - } - i += 1; - } - IResult::Error -} - -pub fn word_break(input: &str) -> IResult<&str, ()> { - match input.chars().next() { - Some(ch) if UnicodeXID::is_xid_continue(ch) => IResult::Error, - Some(_) | None => IResult::Done(input, ()), - } -} - -pub fn skip_whitespace(input: &str) -> &str { - match whitespace(input) { - IResult::Done(rest, _) => rest, - IResult::Error => input, - } -} - -fn is_whitespace(ch: char) -> bool { - // Rust treats left-to-right mark and right-to-left mark as whitespace - ch.is_whitespace() || ch == '\u{200e}' || ch == '\u{200f}' -} diff --git a/third_party/rust/syn-0.10.8/src/ty.rs b/third_party/rust/syn-0.10.8/src/ty.rs deleted file mode 100644 index e10901c5be0a..000000000000 --- a/third_party/rust/syn-0.10.8/src/ty.rs +++ /dev/null @@ -1,826 +0,0 @@ -use super::*; - -/// The different kinds of types recognized by the compiler -#[derive(Debug, Clone, Eq, PartialEq, Hash)] -pub enum Ty { - /// A variable-length array (`[T]`) - Slice(Box), - /// A fixed length array (`[T; n]`) - Array(Box, ConstExpr), - /// A raw pointer (`*const T` or `*mut T`) - Ptr(Box), - /// A reference (`&'a T` or `&'a mut T`) - Rptr(Option, Box), - /// A bare function (e.g. `fn(usize) -> bool`) - BareFn(Box), - /// The never type (`!`) - Never, - /// A tuple (`(A, B, C, D, ...)`) - Tup(Vec), - /// A path (`module::module::...::Type`), optionally - /// "qualified", e.g. ` as SomeTrait>::SomeType`. - /// - /// Type parameters are stored in the Path itself - Path(Option, Path), - /// Something like `A+B`. Note that `B` must always be a path. - ObjectSum(Box, Vec), - /// A type like `for<'a> Foo<&'a Bar>` - PolyTraitRef(Vec), - /// An `impl TraitA+TraitB` type. - ImplTrait(Vec), - /// No-op; kept solely so that we can pretty-print faithfully - Paren(Box), - /// TyKind::Infer means the type should be inferred instead of it having been - /// specified. This can appear anywhere in a type. - Infer, -} - -#[derive(Debug, Clone, Eq, PartialEq, Hash)] -pub struct MutTy { - pub ty: Ty, - pub mutability: Mutability, -} - -#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] -pub enum Mutability { - Mutable, - Immutable, -} - -/// A "Path" is essentially Rust's notion of a name. -/// -/// It's represented as a sequence of identifiers, -/// along with a bunch of supporting information. -/// -/// E.g. `std::cmp::PartialEq` -#[derive(Debug, Clone, Eq, PartialEq, Hash)] -pub struct Path { - pub global: bool, - pub segments: Vec, -} - -impl From for Path - where T: Into -{ - fn from(segment: T) -> Self { - Path { - global: false, - segments: vec![segment.into()], - } - } -} - -/// A segment of a path: an identifier, an optional lifetime, and a set of types. -/// -/// E.g. `std`, `String` or `Box` -#[derive(Debug, Clone, Eq, PartialEq, Hash)] -pub struct PathSegment { - pub ident: Ident, - pub parameters: PathParameters, -} - -impl From for PathSegment - where T: Into -{ - fn from(ident: T) -> Self { - PathSegment { - ident: ident.into(), - parameters: PathParameters::none(), - } - } -} - -/// Parameters of a path segment. -/// -/// E.g. `` as in `Foo` or `(A, B)` as in `Foo(A, B)` -#[derive(Debug, Clone, Eq, PartialEq, Hash)] -pub enum PathParameters { - /// The `<'a, A, B, C>` in `foo::bar::baz::<'a, A, B, C>` - AngleBracketed(AngleBracketedParameterData), - /// The `(A, B)` and `C` in `Foo(A, B) -> C` - Parenthesized(ParenthesizedParameterData), -} - -impl PathParameters { - pub fn none() -> Self { - PathParameters::AngleBracketed(AngleBracketedParameterData::default()) - } - - pub fn is_empty(&self) -> bool { - match *self { - PathParameters::AngleBracketed(ref bracketed) => { - bracketed.lifetimes.is_empty() && bracketed.types.is_empty() && - bracketed.bindings.is_empty() - } - PathParameters::Parenthesized(_) => false, - } - } -} - -/// A path like `Foo<'a, T>` -#[derive(Debug, Clone, Eq, PartialEq, Default, Hash)] -pub struct AngleBracketedParameterData { - /// The lifetime parameters for this path segment. - pub lifetimes: Vec, - /// The type parameters for this path segment, if present. - pub types: Vec, - /// Bindings (equality constraints) on associated types, if present. - /// - /// E.g., `Foo`. - pub bindings: Vec, -} - -/// Bind a type to an associated type: `A=Foo`. -#[derive(Debug, Clone, Eq, PartialEq, Hash)] -pub struct TypeBinding { - pub ident: Ident, - pub ty: Ty, -} - -/// A path like `Foo(A,B) -> C` -#[derive(Debug, Clone, Eq, PartialEq, Hash)] -pub struct ParenthesizedParameterData { - /// `(A, B)` - pub inputs: Vec, - /// `C` - pub output: Option, -} - -#[derive(Debug, Clone, Eq, PartialEq, Hash)] -pub struct PolyTraitRef { - /// The `'a` in `<'a> Foo<&'a T>` - pub bound_lifetimes: Vec, - /// The `Foo<&'a T>` in `<'a> Foo<&'a T>` - pub trait_ref: Path, -} - -/// The explicit Self type in a "qualified path". The actual -/// path, including the trait and the associated item, is stored -/// separately. `position` represents the index of the associated -/// item qualified with this Self type. -/// -/// ```rust,ignore -/// as a::b::Trait>::AssociatedItem -/// ^~~~~ ~~~~~~~~~~~~~~^ -/// ty position = 3 -/// -/// >::AssociatedItem -/// ^~~~~ ^ -/// ty position = 0 -/// ``` -#[derive(Debug, Clone, Eq, PartialEq, Hash)] -pub struct QSelf { - pub ty: Box, - pub position: usize, -} - -#[derive(Debug, Clone, Eq, PartialEq, Hash)] -pub struct BareFnTy { - pub unsafety: Unsafety, - pub abi: Option, - pub lifetimes: Vec, - pub inputs: Vec, - pub output: FunctionRetTy, - pub variadic: bool, -} - -#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] -pub enum Unsafety { - Unsafe, - Normal, -} - -#[derive(Debug, Clone, Eq, PartialEq, Hash)] -pub enum Abi { - Named(String), - Rust, -} - -/// An argument in a function type. -/// -/// E.g. `bar: usize` as in `fn foo(bar: usize)` -#[derive(Debug, Clone, Eq, PartialEq, Hash)] -pub struct BareFnArg { - pub name: Option, - pub ty: Ty, -} - -#[derive(Debug, Clone, Eq, PartialEq, Hash)] -pub enum FunctionRetTy { - /// Return type is not specified. - /// - /// Functions default to `()` and - /// closures default to inference. Span points to where return - /// type would be inserted. - Default, - /// Everything else - Ty(Ty), -} - -#[cfg(feature = "parsing")] -pub mod parsing { - use super::*; - #[cfg(feature = "full")] - use ConstExpr; - use constant::parsing::const_expr; - #[cfg(feature = "full")] - use expr::parsing::expr; - use generics::parsing::{lifetime, lifetime_def, ty_param_bound, bound_lifetimes}; - use ident::parsing::ident; - use lit::parsing::quoted_string; - use std::str; - - named!(pub ty -> Ty, alt!( - ty_paren // must be before ty_tup - | - ty_path // must be before ty_poly_trait_ref - | - ty_vec - | - ty_array - | - ty_ptr - | - ty_rptr - | - ty_bare_fn - | - ty_never - | - ty_tup - | - ty_poly_trait_ref - | - ty_impl_trait - )); - - named!(ty_vec -> Ty, do_parse!( - punct!("[") >> - elem: ty >> - punct!("]") >> - (Ty::Slice(Box::new(elem))) - )); - - #[cfg(not(feature = "full"))] - named!(ty_array -> Ty, do_parse!( - punct!("[") >> - elem: ty >> - punct!(";") >> - len: const_expr >> - punct!("]") >> - (Ty::Array(Box::new(elem), len)) - )); - - #[cfg(feature = "full")] - named!(ty_array -> Ty, do_parse!( - punct!("[") >> - elem: ty >> - punct!(";") >> - len: alt!( - terminated!(const_expr, punct!("]")) - | - terminated!(expr, punct!("]")) => { ConstExpr::Other } - ) >> - (Ty::Array(Box::new(elem), len)) - )); - - named!(ty_ptr -> Ty, do_parse!( - punct!("*") >> - mutability: alt!( - keyword!("const") => { |_| Mutability::Immutable } - | - keyword!("mut") => { |_| Mutability::Mutable } - ) >> - target: ty >> - (Ty::Ptr(Box::new(MutTy { - ty: target, - mutability: mutability, - }))) - )); - - named!(ty_rptr -> Ty, do_parse!( - punct!("&") >> - life: option!(lifetime) >> - mutability: mutability >> - target: ty >> - (Ty::Rptr(life, Box::new(MutTy { - ty: target, - mutability: mutability, - }))) - )); - - named!(ty_bare_fn -> Ty, do_parse!( - lifetimes: opt_vec!(do_parse!( - keyword!("for") >> - punct!("<") >> - lifetimes: terminated_list!(punct!(","), lifetime_def) >> - punct!(">") >> - (lifetimes) - )) >> - unsafety: unsafety >> - abi: option!(abi) >> - keyword!("fn") >> - punct!("(") >> - inputs: separated_list!(punct!(","), fn_arg) >> - trailing_comma: option!(punct!(",")) >> - variadic: option!(cond_reduce!(trailing_comma.is_some(), punct!("..."))) >> - punct!(")") >> - output: option!(preceded!( - punct!("->"), - ty - )) >> - (Ty::BareFn(Box::new(BareFnTy { - unsafety: unsafety, - abi: abi, - lifetimes: lifetimes, - inputs: inputs, - output: match output { - Some(ty) => FunctionRetTy::Ty(ty), - None => FunctionRetTy::Default, - }, - variadic: variadic.is_some(), - }))) - )); - - named!(ty_never -> Ty, map!(punct!("!"), |_| Ty::Never)); - - named!(ty_tup -> Ty, do_parse!( - punct!("(") >> - elems: terminated_list!(punct!(","), ty) >> - punct!(")") >> - (Ty::Tup(elems)) - )); - - named!(ty_path -> Ty, do_parse!( - qpath: qpath >> - parenthesized: cond!( - qpath.1.segments.last().unwrap().parameters == PathParameters::none(), - option!(parenthesized_parameter_data) - ) >> - bounds: many0!(preceded!(punct!("+"), ty_param_bound)) >> - ({ - let (qself, mut path) = qpath; - if let Some(Some(parenthesized)) = parenthesized { - path.segments.last_mut().unwrap().parameters = parenthesized; - } - let path = Ty::Path(qself, path); - if bounds.is_empty() { - path - } else { - Ty::ObjectSum(Box::new(path), bounds) - } - }) - )); - - named!(parenthesized_parameter_data -> PathParameters, do_parse!( - punct!("(") >> - inputs: terminated_list!(punct!(","), ty) >> - punct!(")") >> - output: option!(preceded!( - punct!("->"), - ty - )) >> - (PathParameters::Parenthesized( - ParenthesizedParameterData { - inputs: inputs, - output: output, - }, - )) - )); - - named!(pub qpath -> (Option, Path), alt!( - map!(path, |p| (None, p)) - | - do_parse!( - punct!("<") >> - this: map!(ty, Box::new) >> - path: option!(preceded!( - keyword!("as"), - path - )) >> - punct!(">") >> - punct!("::") >> - rest: separated_nonempty_list!(punct!("::"), path_segment) >> - ({ - match path { - Some(mut path) => { - let pos = path.segments.len(); - path.segments.extend(rest); - (Some(QSelf { ty: this, position: pos }), path) - } - None => { - (Some(QSelf { ty: this, position: 0 }), Path { - global: false, - segments: rest, - }) - } - } - }) - ) - | - map!(keyword!("self"), |_| (None, "self".into())) - )); - - named!(ty_poly_trait_ref -> Ty, map!( - separated_nonempty_list!(punct!("+"), ty_param_bound), - Ty::PolyTraitRef - )); - - named!(ty_impl_trait -> Ty, do_parse!( - keyword!("impl") >> - elem: separated_nonempty_list!(punct!("+"), ty_param_bound) >> - (Ty::ImplTrait(elem)) - )); - - named!(ty_paren -> Ty, do_parse!( - punct!("(") >> - elem: ty >> - punct!(")") >> - (Ty::Paren(Box::new(elem))) - )); - - named!(pub mutability -> Mutability, alt!( - keyword!("mut") => { |_| Mutability::Mutable } - | - epsilon!() => { |_| Mutability::Immutable } - )); - - named!(pub path -> Path, do_parse!( - global: option!(punct!("::")) >> - segments: separated_nonempty_list!(punct!("::"), path_segment) >> - (Path { - global: global.is_some(), - segments: segments, - }) - )); - - named!(path_segment -> PathSegment, alt!( - do_parse!( - id: option!(ident) >> - punct!("<") >> - lifetimes: separated_list!(punct!(","), lifetime) >> - types: opt_vec!(preceded!( - cond!(!lifetimes.is_empty(), punct!(",")), - separated_nonempty_list!( - punct!(","), - terminated!(ty, not!(peek!(punct!("=")))) - ) - )) >> - bindings: opt_vec!(preceded!( - cond!(!lifetimes.is_empty() || !types.is_empty(), punct!(",")), - separated_nonempty_list!(punct!(","), type_binding) - )) >> - cond!(!lifetimes.is_empty() || !types.is_empty() || !bindings.is_empty(), option!(punct!(","))) >> - punct!(">") >> - (PathSegment { - ident: id.unwrap_or_else(|| "".into()), - parameters: PathParameters::AngleBracketed( - AngleBracketedParameterData { - lifetimes: lifetimes, - types: types, - bindings: bindings, - } - ), - }) - ) - | - map!(ident, Into::into) - | - map!(alt!( - keyword!("super") - | - keyword!("self") - | - keyword!("Self") - ), Into::into) - )); - - named!(type_binding -> TypeBinding, do_parse!( - id: ident >> - punct!("=") >> - ty: ty >> - (TypeBinding { - ident: id, - ty: ty, - }) - )); - - named!(pub poly_trait_ref -> PolyTraitRef, do_parse!( - bound_lifetimes: bound_lifetimes >> - trait_ref: path >> - parenthesized: option!(cond_reduce!( - trait_ref.segments.last().unwrap().parameters == PathParameters::none(), - parenthesized_parameter_data - )) >> - ({ - let mut trait_ref = trait_ref; - if let Some(parenthesized) = parenthesized { - trait_ref.segments.last_mut().unwrap().parameters = parenthesized; - } - PolyTraitRef { - bound_lifetimes: bound_lifetimes, - trait_ref: trait_ref, - } - }) - )); - - named!(pub fn_arg -> BareFnArg, do_parse!( - name: option!(do_parse!( - name: ident >> - punct!(":") >> - not!(peek!(tag!(":"))) >> // not :: - (name) - )) >> - ty: ty >> - (BareFnArg { - name: name, - ty: ty, - }) - )); - - named!(pub unsafety -> Unsafety, alt!( - keyword!("unsafe") => { |_| Unsafety::Unsafe } - | - epsilon!() => { |_| Unsafety::Normal } - )); - - named!(pub abi -> Abi, do_parse!( - keyword!("extern") >> - name: option!(quoted_string) >> - (match name { - Some(name) => Abi::Named(name), - None => Abi::Rust, - }) - )); -} - -#[cfg(feature = "printing")] -mod printing { - use super::*; - use quote::{Tokens, ToTokens}; - - impl ToTokens for Ty { - fn to_tokens(&self, tokens: &mut Tokens) { - match *self { - Ty::Slice(ref inner) => { - tokens.append("["); - inner.to_tokens(tokens); - tokens.append("]"); - } - Ty::Array(ref inner, ref len) => { - tokens.append("["); - inner.to_tokens(tokens); - tokens.append(";"); - len.to_tokens(tokens); - tokens.append("]"); - } - Ty::Ptr(ref target) => { - tokens.append("*"); - match target.mutability { - Mutability::Mutable => tokens.append("mut"), - Mutability::Immutable => tokens.append("const"), - } - target.ty.to_tokens(tokens); - } - Ty::Rptr(ref lifetime, ref target) => { - tokens.append("&"); - lifetime.to_tokens(tokens); - target.mutability.to_tokens(tokens); - target.ty.to_tokens(tokens); - } - Ty::BareFn(ref func) => { - func.to_tokens(tokens); - } - Ty::Never => { - tokens.append("!"); - } - Ty::Tup(ref elems) => { - tokens.append("("); - tokens.append_separated(elems, ","); - if elems.len() == 1 { - tokens.append(","); - } - tokens.append(")"); - } - Ty::Path(None, ref path) => { - path.to_tokens(tokens); - } - Ty::Path(Some(ref qself), ref path) => { - tokens.append("<"); - qself.ty.to_tokens(tokens); - if qself.position > 0 { - tokens.append("as"); - for (i, segment) in path.segments - .iter() - .take(qself.position) - .enumerate() { - if i > 0 || path.global { - tokens.append("::"); - } - segment.to_tokens(tokens); - } - } - tokens.append(">"); - for segment in path.segments.iter().skip(qself.position) { - tokens.append("::"); - segment.to_tokens(tokens); - } - } - Ty::ObjectSum(ref ty, ref bounds) => { - ty.to_tokens(tokens); - for bound in bounds { - tokens.append("+"); - bound.to_tokens(tokens); - } - } - Ty::PolyTraitRef(ref bounds) => { - tokens.append_separated(bounds, "+"); - } - Ty::ImplTrait(ref bounds) => { - tokens.append("impl"); - tokens.append_separated(bounds, "+"); - } - Ty::Paren(ref inner) => { - tokens.append("("); - inner.to_tokens(tokens); - tokens.append(")"); - } - Ty::Infer => { - tokens.append("_"); - } - } - } - } - - impl ToTokens for Mutability { - fn to_tokens(&self, tokens: &mut Tokens) { - if let Mutability::Mutable = *self { - tokens.append("mut"); - } - } - } - - impl ToTokens for Path { - fn to_tokens(&self, tokens: &mut Tokens) { - for (i, segment) in self.segments.iter().enumerate() { - if i > 0 || self.global { - tokens.append("::"); - } - segment.to_tokens(tokens); - } - } - } - - impl ToTokens for PathSegment { - fn to_tokens(&self, tokens: &mut Tokens) { - self.ident.to_tokens(tokens); - if self.ident.as_ref().is_empty() && self.parameters.is_empty() { - tokens.append("<"); - tokens.append(">"); - } else { - self.parameters.to_tokens(tokens); - } - } - } - - impl ToTokens for PathParameters { - fn to_tokens(&self, tokens: &mut Tokens) { - match *self { - PathParameters::AngleBracketed(ref parameters) => { - parameters.to_tokens(tokens); - } - PathParameters::Parenthesized(ref parameters) => { - parameters.to_tokens(tokens); - } - } - } - } - - impl ToTokens for AngleBracketedParameterData { - fn to_tokens(&self, tokens: &mut Tokens) { - let has_lifetimes = !self.lifetimes.is_empty(); - let has_types = !self.types.is_empty(); - let has_bindings = !self.bindings.is_empty(); - if !has_lifetimes && !has_types && !has_bindings { - return; - } - - tokens.append("<"); - - let mut first = true; - for lifetime in &self.lifetimes { - if !first { - tokens.append(","); - } - lifetime.to_tokens(tokens); - first = false; - } - for ty in &self.types { - if !first { - tokens.append(","); - } - ty.to_tokens(tokens); - first = false; - } - for binding in &self.bindings { - if !first { - tokens.append(","); - } - binding.to_tokens(tokens); - first = false; - } - - tokens.append(">"); - } - } - - impl ToTokens for TypeBinding { - fn to_tokens(&self, tokens: &mut Tokens) { - self.ident.to_tokens(tokens); - tokens.append("="); - self.ty.to_tokens(tokens); - } - } - - impl ToTokens for ParenthesizedParameterData { - fn to_tokens(&self, tokens: &mut Tokens) { - tokens.append("("); - tokens.append_separated(&self.inputs, ","); - tokens.append(")"); - if let Some(ref output) = self.output { - tokens.append("->"); - output.to_tokens(tokens); - } - } - } - - impl ToTokens for PolyTraitRef { - fn to_tokens(&self, tokens: &mut Tokens) { - if !self.bound_lifetimes.is_empty() { - tokens.append("for"); - tokens.append("<"); - tokens.append_separated(&self.bound_lifetimes, ","); - tokens.append(">"); - } - self.trait_ref.to_tokens(tokens); - } - } - - impl ToTokens for BareFnTy { - fn to_tokens(&self, tokens: &mut Tokens) { - if !self.lifetimes.is_empty() { - tokens.append("for"); - tokens.append("<"); - tokens.append_separated(&self.lifetimes, ","); - tokens.append(">"); - } - self.unsafety.to_tokens(tokens); - self.abi.to_tokens(tokens); - tokens.append("fn"); - tokens.append("("); - tokens.append_separated(&self.inputs, ","); - if self.variadic { - if !self.inputs.is_empty() { - tokens.append(","); - } - tokens.append("..."); - } - tokens.append(")"); - if let FunctionRetTy::Ty(ref ty) = self.output { - tokens.append("->"); - ty.to_tokens(tokens); - } - } - } - - impl ToTokens for BareFnArg { - fn to_tokens(&self, tokens: &mut Tokens) { - if let Some(ref name) = self.name { - name.to_tokens(tokens); - tokens.append(":"); - } - self.ty.to_tokens(tokens); - } - } - - impl ToTokens for Unsafety { - fn to_tokens(&self, tokens: &mut Tokens) { - match *self { - Unsafety::Unsafe => tokens.append("unsafe"), - Unsafety::Normal => { - // nothing - } - } - } - } - - impl ToTokens for Abi { - fn to_tokens(&self, tokens: &mut Tokens) { - tokens.append("extern"); - match *self { - Abi::Named(ref named) => named.to_tokens(tokens), - Abi::Rust => {} - } - } - } -} diff --git a/third_party/rust/syn-0.10.8/src/visit.rs b/third_party/rust/syn-0.10.8/src/visit.rs deleted file mode 100644 index e23f3f0f2dcd..000000000000 --- a/third_party/rust/syn-0.10.8/src/visit.rs +++ /dev/null @@ -1,295 +0,0 @@ -// Adapted from libsyntax. - -//! AST walker. Each overridden visit method has full control over what -//! happens with its node, it can do its own traversal of the node's children, -//! call `visit::walk_*` to apply the default traversal algorithm, or prevent -//! deeper traversal by doing nothing. -//! -//! Note: it is an important invariant that the default visitor walks the body -//! of a function in "execution order" (more concretely, reverse post-order -//! with respect to the CFG implied by the AST), meaning that if AST node A may -//! execute before AST node B, then A is visited first. The borrow checker in -//! particular relies on this property. -//! -//! Note: walking an AST before macro expansion is probably a bad idea. For -//! instance, a walker looking for item names in a module will miss all of -//! those that are created by the expansion of a macro. - -use super::*; - -/// Each method of the Visitor trait is a hook to be potentially -/// overridden. Each method's default implementation recursively visits -/// the substructure of the input via the corresponding `walk` method; -/// e.g. the `visit_mod` method by default calls `visit::walk_mod`. -/// -/// If you want to ensure that your code handles every variant -/// explicitly, you need to override each method. (And you also need -/// to monitor future changes to `Visitor` in case a new method with a -/// new default implementation gets introduced.) -pub trait Visitor: Sized { - fn visit_ident(&mut self, _ident: &Ident) {} - fn visit_macro_input(&mut self, macro_input: &MacroInput) { - walk_macro_input(self, macro_input) - } - fn visit_ty(&mut self, ty: &Ty) { - walk_ty(self, ty) - } - fn visit_generics(&mut self, generics: &Generics) { - walk_generics(self, generics) - } - fn visit_ty_param_bound(&mut self, bound: &TyParamBound) { - walk_ty_param_bound(self, bound) - } - fn visit_poly_trait_ref(&mut self, trait_ref: &PolyTraitRef, modifier: &TraitBoundModifier) { - walk_poly_trait_ref(self, trait_ref, modifier) - } - fn visit_variant_data(&mut self, data: &VariantData, _ident: &Ident, _generics: &Generics) { - walk_variant_data(self, data) - } - fn visit_field(&mut self, field: &Field) { - walk_field(self, field) - } - fn visit_variant(&mut self, variant: &Variant, generics: &Generics) { - walk_variant(self, variant, generics) - } - fn visit_lifetime(&mut self, _lifetime: &Lifetime) {} - fn visit_lifetime_def(&mut self, lifetime: &LifetimeDef) { - walk_lifetime_def(self, lifetime) - } - fn visit_path(&mut self, path: &Path) { - walk_path(self, path) - } - fn visit_path_segment(&mut self, path_segment: &PathSegment) { - walk_path_segment(self, path_segment) - } - fn visit_path_parameters(&mut self, path_parameters: &PathParameters) { - walk_path_parameters(self, path_parameters) - } - fn visit_assoc_type_binding(&mut self, type_binding: &TypeBinding) { - walk_assoc_type_binding(self, type_binding) - } - fn visit_attribute(&mut self, _attr: &Attribute) {} - fn visit_fn_ret_ty(&mut self, ret_ty: &FunctionRetTy) { - walk_fn_ret_ty(self, ret_ty) - } - fn visit_const_expr(&mut self, expr: &ConstExpr) { - walk_const_expr(self, expr) - } - fn visit_lit(&mut self, _lit: &Lit) {} -} - -#[macro_export] -macro_rules! walk_list { - ($visitor: expr, $method: ident, $list: expr) => { - for elem in $list { - $visitor.$method(elem) - } - }; - ($visitor: expr, $method: ident, $list: expr, $($extra_args: expr),*) => { - for elem in $list { - $visitor.$method(elem, $($extra_args,)*) - } - } -} - -pub fn walk_opt_ident(visitor: &mut V, opt_ident: &Option) { - if let Some(ref ident) = *opt_ident { - visitor.visit_ident(ident); - } -} - -pub fn walk_lifetime_def(visitor: &mut V, lifetime_def: &LifetimeDef) { - visitor.visit_lifetime(&lifetime_def.lifetime); - walk_list!(visitor, visit_lifetime, &lifetime_def.bounds); -} - -pub fn walk_poly_trait_ref(visitor: &mut V, trait_ref: &PolyTraitRef, _: &TraitBoundModifier) - where V: Visitor -{ - walk_list!(visitor, visit_lifetime_def, &trait_ref.bound_lifetimes); - visitor.visit_path(&trait_ref.trait_ref); -} - -pub fn walk_macro_input(visitor: &mut V, macro_input: &MacroInput) { - visitor.visit_ident(¯o_input.ident); - visitor.visit_generics(¯o_input.generics); - match macro_input.body { - Body::Enum(ref variants) => { - walk_list!(visitor, visit_variant, variants, ¯o_input.generics); - } - Body::Struct(ref variant_data) => { - visitor.visit_variant_data(variant_data, ¯o_input.ident, ¯o_input.generics); - } - } - walk_list!(visitor, visit_attribute, ¯o_input.attrs); -} - -pub fn walk_variant(visitor: &mut V, variant: &Variant, generics: &Generics) - where V: Visitor -{ - visitor.visit_ident(&variant.ident); - visitor.visit_variant_data(&variant.data, &variant.ident, generics); - walk_list!(visitor, visit_attribute, &variant.attrs); -} - -pub fn walk_ty(visitor: &mut V, ty: &Ty) { - match *ty { - Ty::Slice(ref inner) | - Ty::Paren(ref inner) => visitor.visit_ty(inner), - Ty::Ptr(ref mutable_type) => visitor.visit_ty(&mutable_type.ty), - Ty::Rptr(ref opt_lifetime, ref mutable_type) => { - walk_list!(visitor, visit_lifetime, opt_lifetime); - visitor.visit_ty(&mutable_type.ty) - } - Ty::Never | Ty::Infer => {} - Ty::Tup(ref tuple_element_types) => { - walk_list!(visitor, visit_ty, tuple_element_types); - } - Ty::BareFn(ref bare_fn) => { - walk_list!(visitor, visit_lifetime_def, &bare_fn.lifetimes); - for argument in &bare_fn.inputs { - walk_opt_ident(visitor, &argument.name); - visitor.visit_ty(&argument.ty) - } - visitor.visit_fn_ret_ty(&bare_fn.output) - } - Ty::Path(ref maybe_qself, ref path) => { - if let Some(ref qself) = *maybe_qself { - visitor.visit_ty(&qself.ty); - } - visitor.visit_path(path); - } - Ty::ObjectSum(ref inner, ref bounds) => { - visitor.visit_ty(inner); - walk_list!(visitor, visit_ty_param_bound, bounds); - } - Ty::Array(ref inner, ref len) => { - visitor.visit_ty(inner); - visitor.visit_const_expr(len); - } - Ty::PolyTraitRef(ref bounds) | - Ty::ImplTrait(ref bounds) => { - walk_list!(visitor, visit_ty_param_bound, bounds); - } - } -} - -pub fn walk_path(visitor: &mut V, path: &Path) { - for segment in &path.segments { - visitor.visit_path_segment(segment); - } -} - -pub fn walk_path_segment(visitor: &mut V, segment: &PathSegment) { - visitor.visit_ident(&segment.ident); - visitor.visit_path_parameters(&segment.parameters); -} - -pub fn walk_path_parameters(visitor: &mut V, path_parameters: &PathParameters) - where V: Visitor -{ - match *path_parameters { - PathParameters::AngleBracketed(ref data) => { - walk_list!(visitor, visit_ty, &data.types); - walk_list!(visitor, visit_lifetime, &data.lifetimes); - walk_list!(visitor, visit_assoc_type_binding, &data.bindings); - } - PathParameters::Parenthesized(ref data) => { - walk_list!(visitor, visit_ty, &data.inputs); - walk_list!(visitor, visit_ty, &data.output); - } - } -} - -pub fn walk_assoc_type_binding(visitor: &mut V, type_binding: &TypeBinding) { - visitor.visit_ident(&type_binding.ident); - visitor.visit_ty(&type_binding.ty); -} - -pub fn walk_ty_param_bound(visitor: &mut V, bound: &TyParamBound) { - match *bound { - TyParamBound::Trait(ref ty, ref modifier) => { - visitor.visit_poly_trait_ref(ty, modifier); - } - TyParamBound::Region(ref lifetime) => { - visitor.visit_lifetime(lifetime); - } - } -} - -pub fn walk_generics(visitor: &mut V, generics: &Generics) { - for param in &generics.ty_params { - visitor.visit_ident(¶m.ident); - walk_list!(visitor, visit_ty_param_bound, ¶m.bounds); - walk_list!(visitor, visit_ty, ¶m.default); - } - walk_list!(visitor, visit_lifetime_def, &generics.lifetimes); - for predicate in &generics.where_clause.predicates { - match *predicate { - WherePredicate::BoundPredicate(WhereBoundPredicate { ref bounded_ty, - ref bounds, - ref bound_lifetimes, - .. }) => { - visitor.visit_ty(bounded_ty); - walk_list!(visitor, visit_ty_param_bound, bounds); - walk_list!(visitor, visit_lifetime_def, bound_lifetimes); - } - WherePredicate::RegionPredicate(WhereRegionPredicate { ref lifetime, - ref bounds, - .. }) => { - visitor.visit_lifetime(lifetime); - walk_list!(visitor, visit_lifetime, bounds); - } - } - } -} - -pub fn walk_fn_ret_ty(visitor: &mut V, ret_ty: &FunctionRetTy) { - if let FunctionRetTy::Ty(ref output_ty) = *ret_ty { - visitor.visit_ty(output_ty) - } -} - -pub fn walk_variant_data(visitor: &mut V, data: &VariantData) { - walk_list!(visitor, visit_field, data.fields()); -} - -pub fn walk_field(visitor: &mut V, field: &Field) { - walk_opt_ident(visitor, &field.ident); - visitor.visit_ty(&field.ty); - walk_list!(visitor, visit_attribute, &field.attrs); -} - -pub fn walk_const_expr(visitor: &mut V, len: &ConstExpr) { - match *len { - ConstExpr::Call(ref function, ref args) => { - visitor.visit_const_expr(function); - walk_list!(visitor, visit_const_expr, args); - } - ConstExpr::Binary(_op, ref left, ref right) => { - visitor.visit_const_expr(left); - visitor.visit_const_expr(right); - } - ConstExpr::Unary(_op, ref v) => { - visitor.visit_const_expr(v); - } - ConstExpr::Lit(ref lit) => { - visitor.visit_lit(lit); - } - ConstExpr::Cast(ref expr, ref ty) => { - visitor.visit_const_expr(expr); - visitor.visit_ty(ty); - } - ConstExpr::Path(ref path) => { - visitor.visit_path(path); - } - ConstExpr::Index(ref expr, ref index) => { - visitor.visit_const_expr(expr); - visitor.visit_const_expr(index); - } - ConstExpr::Paren(ref expr) => { - visitor.visit_const_expr(expr); - } - ConstExpr::Other(_) => {} - } -} diff --git a/toolkit/library/gtest/rust/Cargo.lock b/toolkit/library/gtest/rust/Cargo.lock index 2561f3856303..c953214824a4 100644 --- a/toolkit/library/gtest/rust/Cargo.lock +++ b/toolkit/library/gtest/rust/Cargo.lock @@ -225,6 +225,20 @@ name = "dtoa" version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "dwrote" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "gdi32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 0.9.9 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 0.9.11 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "encoding" version = "0.2.33" @@ -765,23 +779,21 @@ version = "0.9.9" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] -name = "serde_codegen" -version = "0.9.0" +name = "serde_codegen_internals" +version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "quote 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_codegen_internals 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.10.8 (registry+https://github.com/rust-lang/crates.io-index)", - "syntex 0.54.0 (registry+https://github.com/rust-lang/crates.io-index)", - "syntex_syntax 0.54.0 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.11.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "serde_codegen_internals" -version = "0.11.3" +name = "serde_derive" +version = "0.9.11" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "syn 0.10.8 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_codegen_internals 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.11.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -795,20 +807,6 @@ dependencies = [ "serde 0.9.9 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "servo-dwrote" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "gdi32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 0.9.9 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_codegen 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "servo_config" version = "0.0.1" @@ -922,15 +920,6 @@ dependencies = [ "euclid 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "syn" -version = "0.10.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "quote 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "syn" version = "0.11.8" @@ -1156,7 +1145,7 @@ dependencies = [ [[package]] name = "webrender" -version = "0.19.0" +version = "0.22.1" dependencies = [ "app_units 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "bincode 1.0.0-alpha4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1165,6 +1154,7 @@ dependencies = [ "byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "core-graphics 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "core-text 4.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "dwrote 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "euclid 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "freetype 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1174,11 +1164,10 @@ dependencies = [ "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", "offscreen_gl_context 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", - "servo-dwrote 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "thread_profiler 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "threadpool 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)", - "webrender_traits 0.20.0", + "webrender_traits 0.23.1", ] [[package]] @@ -1188,24 +1177,24 @@ dependencies = [ "app_units 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "euclid 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "gleam 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)", - "webrender 0.19.0", - "webrender_traits 0.20.0", + "webrender 0.22.1", + "webrender_traits 0.23.1", ] [[package]] name = "webrender_traits" -version = "0.20.0" +version = "0.23.1" dependencies = [ "app_units 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "core-graphics 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "dwrote 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "euclid 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "gleam 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)", "heapsize 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", "offscreen_gl_context 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde 0.9.9 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_codegen 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "servo-dwrote 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 0.9.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1266,6 +1255,7 @@ dependencies = [ "checksum cssparser-macros 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b8f0415de0bdbce823c0db204e00a62c8240fa2d3e04cd13ff7c6396e4446b95" "checksum deque 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1614659040e711785ed8ea24219140654da1729f3ec8a47a9719d041112fe7bf" "checksum dtoa 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "80c8b71fd71146990a9742fc06dcbbde19161a267e0ad4e572c35162f4578c90" +"checksum dwrote 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "74114b6b49d6731835da7a28a3642651451e315f7f9b9d04e907e65a45681796" "checksum encoding 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "6b0d943856b990d12d3b55b359144ff341533e516d94098b1d3fc1ac666d36ec" "checksum encoding-index-japanese 1.20141219.5 (registry+https://github.com/rust-lang/crates.io-index)" = "04e8b2ff42e9a05335dbf8b5c6f7567e5591d0d916ccef4e0b1710d32a0d0c91" "checksum encoding-index-korean 1.20141219.5 (registry+https://github.com/rust-lang/crates.io-index)" = "4dc33fb8e6bcba213fe2f14275f0963fd16f0a02c878e3095ecfdf5bee529d81" @@ -1324,15 +1314,13 @@ dependencies = [ "checksum rustc-serialize 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)" = "237546c689f20bb44980270c73c3b9edd0891c1be49cc1274406134a66d3957b" "checksum same-file 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d931a44fdaa43b8637009e7632a02adc4f2b2e0733c08caa4cf00e8da4a117a7" "checksum serde 0.9.9 (registry+https://github.com/rust-lang/crates.io-index)" = "05a67b8a53f885f4b6e3ed183806035819f9862474e747fe4488a6d63bcbfcb7" -"checksum serde_codegen 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1f94de585a73dfc312ca77194209278a587bf90d3edc6c2d0fc479b0ed71d1f0" -"checksum serde_codegen_internals 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "afad7924a009f859f380e4a2e3a509a845c2ac66435fcead74a4d983b21ae806" +"checksum serde_codegen_internals 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4d52006899f910528a10631e5b727973fe668f3228109d1707ccf5bad5490b6e" +"checksum serde_derive 0.9.11 (registry+https://github.com/rust-lang/crates.io-index)" = "f15ea24bd037b2d64646b4d934fa99c649be66e3f7b29fb595a5543b212b1452" "checksum serde_json 0.9.8 (registry+https://github.com/rust-lang/crates.io-index)" = "6501ac6f8b74f9b1033f7ddf79a08edfa0f58d6f8e3190cb8dc97736afa257a8" -"checksum servo-dwrote 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9f013da79c3fb2a9653534b064cd2ca62e10f8b6d19ed8fdc885cb2873412789" "checksum shared_library 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "fb04126b6fcfd2710fb5b6d18f4207b6c535f2850a7e1a43bcd526d44f30a79a" "checksum siphasher 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2ffc669b726f2bc9a3bcff66e5e23b56ba6bf70e22a34c3d7b6d0b3450b65b84" "checksum smallvec 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "fcc8d19212aacecf95e4a7a2179b26f7aeb9732a915cf01f05b0d3e044865410" "checksum strsim 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b4d15c810519a91cf877e7e36e63fe068815c678181439f2f29e2562147c3694" -"checksum syn 0.10.8 (registry+https://github.com/rust-lang/crates.io-index)" = "58fd09df59565db3399efbba34ba8a2fec1307511ebd245d0061ff9d42691673" "checksum syn 0.11.8 (registry+https://github.com/rust-lang/crates.io-index)" = "37c279fb816210c9bb28b2c292664581e7b87b4561e86b94df462664d8620bb8" "checksum synom 0.11.2 (registry+https://github.com/rust-lang/crates.io-index)" = "27e31aa4b09b9f4cb12dff3c30ba503e17b1a624413d764d32dab76e3920e5bc" "checksum syntex 0.54.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb3f52553a966675982404dc34028291b347e0c9a9c0b0b34f2da6be8a0443f8" diff --git a/toolkit/library/rust/Cargo.lock b/toolkit/library/rust/Cargo.lock index d69359a9a640..2c3fda693887 100644 --- a/toolkit/library/rust/Cargo.lock +++ b/toolkit/library/rust/Cargo.lock @@ -223,6 +223,20 @@ name = "dtoa" version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "dwrote" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "gdi32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 0.9.9 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 0.9.11 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "encoding" version = "0.2.33" @@ -752,23 +766,21 @@ version = "0.9.9" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] -name = "serde_codegen" -version = "0.9.0" +name = "serde_codegen_internals" +version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "quote 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_codegen_internals 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.10.8 (registry+https://github.com/rust-lang/crates.io-index)", - "syntex 0.54.0 (registry+https://github.com/rust-lang/crates.io-index)", - "syntex_syntax 0.54.0 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.11.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "serde_codegen_internals" -version = "0.11.3" +name = "serde_derive" +version = "0.9.11" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "syn 0.10.8 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_codegen_internals 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.11.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -782,20 +794,6 @@ dependencies = [ "serde 0.9.9 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "servo-dwrote" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "gdi32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 0.9.9 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_codegen 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "servo_config" version = "0.0.1" @@ -909,15 +907,6 @@ dependencies = [ "euclid 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "syn" -version = "0.10.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "quote 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "syn" version = "0.11.8" @@ -1143,7 +1132,7 @@ dependencies = [ [[package]] name = "webrender" -version = "0.19.0" +version = "0.22.1" dependencies = [ "app_units 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "bincode 1.0.0-alpha4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1152,6 +1141,7 @@ dependencies = [ "byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "core-graphics 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "core-text 4.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "dwrote 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "euclid 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "freetype 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1161,11 +1151,10 @@ dependencies = [ "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", "offscreen_gl_context 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", - "servo-dwrote 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "thread_profiler 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "threadpool 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)", - "webrender_traits 0.20.0", + "webrender_traits 0.23.1", ] [[package]] @@ -1175,24 +1164,24 @@ dependencies = [ "app_units 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "euclid 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "gleam 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)", - "webrender 0.19.0", - "webrender_traits 0.20.0", + "webrender 0.22.1", + "webrender_traits 0.23.1", ] [[package]] name = "webrender_traits" -version = "0.20.0" +version = "0.23.1" dependencies = [ "app_units 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "core-graphics 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "dwrote 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "euclid 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "gleam 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)", "heapsize 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", "offscreen_gl_context 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde 0.9.9 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_codegen 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "servo-dwrote 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 0.9.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1253,6 +1242,7 @@ dependencies = [ "checksum cssparser-macros 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b8f0415de0bdbce823c0db204e00a62c8240fa2d3e04cd13ff7c6396e4446b95" "checksum deque 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1614659040e711785ed8ea24219140654da1729f3ec8a47a9719d041112fe7bf" "checksum dtoa 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "80c8b71fd71146990a9742fc06dcbbde19161a267e0ad4e572c35162f4578c90" +"checksum dwrote 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "74114b6b49d6731835da7a28a3642651451e315f7f9b9d04e907e65a45681796" "checksum encoding 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "6b0d943856b990d12d3b55b359144ff341533e516d94098b1d3fc1ac666d36ec" "checksum encoding-index-japanese 1.20141219.5 (registry+https://github.com/rust-lang/crates.io-index)" = "04e8b2ff42e9a05335dbf8b5c6f7567e5591d0d916ccef4e0b1710d32a0d0c91" "checksum encoding-index-korean 1.20141219.5 (registry+https://github.com/rust-lang/crates.io-index)" = "4dc33fb8e6bcba213fe2f14275f0963fd16f0a02c878e3095ecfdf5bee529d81" @@ -1311,15 +1301,13 @@ dependencies = [ "checksum rustc-serialize 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)" = "237546c689f20bb44980270c73c3b9edd0891c1be49cc1274406134a66d3957b" "checksum same-file 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d931a44fdaa43b8637009e7632a02adc4f2b2e0733c08caa4cf00e8da4a117a7" "checksum serde 0.9.9 (registry+https://github.com/rust-lang/crates.io-index)" = "05a67b8a53f885f4b6e3ed183806035819f9862474e747fe4488a6d63bcbfcb7" -"checksum serde_codegen 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1f94de585a73dfc312ca77194209278a587bf90d3edc6c2d0fc479b0ed71d1f0" -"checksum serde_codegen_internals 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "afad7924a009f859f380e4a2e3a509a845c2ac66435fcead74a4d983b21ae806" +"checksum serde_codegen_internals 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4d52006899f910528a10631e5b727973fe668f3228109d1707ccf5bad5490b6e" +"checksum serde_derive 0.9.11 (registry+https://github.com/rust-lang/crates.io-index)" = "f15ea24bd037b2d64646b4d934fa99c649be66e3f7b29fb595a5543b212b1452" "checksum serde_json 0.9.8 (registry+https://github.com/rust-lang/crates.io-index)" = "6501ac6f8b74f9b1033f7ddf79a08edfa0f58d6f8e3190cb8dc97736afa257a8" -"checksum servo-dwrote 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9f013da79c3fb2a9653534b064cd2ca62e10f8b6d19ed8fdc885cb2873412789" "checksum shared_library 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "fb04126b6fcfd2710fb5b6d18f4207b6c535f2850a7e1a43bcd526d44f30a79a" "checksum siphasher 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2ffc669b726f2bc9a3bcff66e5e23b56ba6bf70e22a34c3d7b6d0b3450b65b84" "checksum smallvec 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "fcc8d19212aacecf95e4a7a2179b26f7aeb9732a915cf01f05b0d3e044865410" "checksum strsim 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b4d15c810519a91cf877e7e36e63fe068815c678181439f2f29e2562147c3694" -"checksum syn 0.10.8 (registry+https://github.com/rust-lang/crates.io-index)" = "58fd09df59565db3399efbba34ba8a2fec1307511ebd245d0061ff9d42691673" "checksum syn 0.11.8 (registry+https://github.com/rust-lang/crates.io-index)" = "37c279fb816210c9bb28b2c292664581e7b87b4561e86b94df462664d8620bb8" "checksum synom 0.11.2 (registry+https://github.com/rust-lang/crates.io-index)" = "27e31aa4b09b9f4cb12dff3c30ba503e17b1a624413d764d32dab76e3920e5bc" "checksum syntex 0.54.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb3f52553a966675982404dc34028291b347e0c9a9c0b0b34f2da6be8a0443f8"

(mut self, path: P) -> Self - where P: IntoPath - { - let path = path.into_path(); - - for ty_param in &mut self.ty_params { - *ty_param = TyParamBuilder::from_ty_param(ty_param.clone()) - .trait_bound(path.clone()) - .build() - .build(); - } - - self - } - - pub fn strip_bounds(self) -> Self { - self.strip_lifetimes() - .strip_ty_params() - .strip_predicates() - } - - pub fn strip_lifetimes(mut self) -> Self { - for lifetime in &mut self.lifetimes { - lifetime.bounds = vec![]; - } - self - } - - pub fn strip_ty_params(mut self) -> Self { - for ty_param in &mut self.ty_params { - ty_param.bounds = vec![]; - } - self - } - - pub fn strip_predicates(mut self) -> Self { - self.predicates = vec![]; - self - } - - pub fn build(self) -> F::Result { - self.callback.invoke(Generics { - lifetimes: self.lifetimes, - ty_params: self.ty_params, - where_clause: WhereClause { predicates: self.predicates }, - }) - } -} - -impl Invoke for GenericsBuilder - where F: Invoke -{ - type Result = Self; - - fn invoke(self, lifetime: LifetimeDef) -> Self { - self.with_lifetime(lifetime) - } -} - -impl Invoke for GenericsBuilder - where F: Invoke -{ - type Result = Self; - - fn invoke(self, ty_param: TyParam) -> Self { - self.with_ty_param(ty_param) - } -} - -impl Invoke for GenericsBuilder - where F: Invoke -{ - type Result = Self; - - fn invoke(self, predicate: WherePredicate) -> Self { - self.with_predicate(predicate) - } -} diff --git a/third_party/rust/syn-0.10.8/src/aster/ident.rs b/third_party/rust/syn-0.10.8/src/aster/ident.rs deleted file mode 100644 index 0c2473fae5dc..000000000000 --- a/third_party/rust/syn-0.10.8/src/aster/ident.rs +++ /dev/null @@ -1,39 +0,0 @@ -use Ident; - -pub trait ToIdent { - fn to_ident(&self) -> Ident; -} - -impl ToIdent for Ident { - fn to_ident(&self) -> Ident { - self.clone() - } -} - -impl<'a> ToIdent for &'a str { - fn to_ident(&self) -> Ident { - (**self).into() - } -} - -impl ToIdent for String { - fn to_ident(&self) -> Ident { - self.clone().into() - } -} - -impl<'a, T> ToIdent for &'a T - where T: ToIdent -{ - fn to_ident(&self) -> Ident { - (**self).to_ident() - } -} - -impl<'a, T> ToIdent for &'a mut T - where T: ToIdent -{ - fn to_ident(&self) -> Ident { - (**self).to_ident() - } -} diff --git a/third_party/rust/syn-0.10.8/src/aster/invoke.rs b/third_party/rust/syn-0.10.8/src/aster/invoke.rs deleted file mode 100644 index 76ae96757c52..000000000000 --- a/third_party/rust/syn-0.10.8/src/aster/invoke.rs +++ /dev/null @@ -1,16 +0,0 @@ -pub trait Invoke { - type Result; - - fn invoke(self, arg: A) -> Self::Result; -} - -#[derive(Copy, Clone)] -pub struct Identity; - -impl Invoke for Identity { - type Result = A; - - fn invoke(self, arg: A) -> A { - arg - } -} diff --git a/third_party/rust/syn-0.10.8/src/aster/lifetime.rs b/third_party/rust/syn-0.10.8/src/aster/lifetime.rs deleted file mode 100644 index 49df4a0d4835..000000000000 --- a/third_party/rust/syn-0.10.8/src/aster/lifetime.rs +++ /dev/null @@ -1,103 +0,0 @@ -use {Ident, Lifetime, LifetimeDef}; -use aster::invoke::{Invoke, Identity}; - -// //////////////////////////////////////////////////////////////////////////// - -pub trait IntoLifetime { - fn into_lifetime(self) -> Lifetime; -} - -impl IntoLifetime for Lifetime { - fn into_lifetime(self) -> Lifetime { - self - } -} - -impl<'a> IntoLifetime for &'a str { - fn into_lifetime(self) -> Lifetime { - Lifetime { ident: self.into() } - } -} - -// //////////////////////////////////////////////////////////////////////////// - -pub trait IntoLifetimeDef { - fn into_lifetime_def(self) -> LifetimeDef; -} - -impl IntoLifetimeDef for LifetimeDef { - fn into_lifetime_def(self) -> LifetimeDef { - self - } -} - -impl IntoLifetimeDef for Lifetime { - fn into_lifetime_def(self) -> LifetimeDef { - LifetimeDef { - attrs: vec![], - lifetime: self, - bounds: vec![], - } - } -} - -impl<'a> IntoLifetimeDef for &'a str { - fn into_lifetime_def(self) -> LifetimeDef { - self.into_lifetime().into_lifetime_def() - } -} - -impl IntoLifetimeDef for String { - fn into_lifetime_def(self) -> LifetimeDef { - (*self).into_lifetime().into_lifetime_def() - } -} - -// //////////////////////////////////////////////////////////////////////////// - -pub struct LifetimeDefBuilder { - callback: F, - lifetime: Lifetime, - bounds: Vec, -} - -impl LifetimeDefBuilder { - pub fn new(name: N) -> Self - where N: Into - { - LifetimeDefBuilder::with_callback(name, Identity) - } -} - -impl LifetimeDefBuilder - where F: Invoke -{ - pub fn with_callback(name: N, callback: F) -> Self - where N: Into - { - let lifetime = Lifetime { ident: name.into() }; - - LifetimeDefBuilder { - callback: callback, - lifetime: lifetime, - bounds: Vec::new(), - } - } - - pub fn bound(mut self, name: N) -> Self - where N: Into - { - let lifetime = Lifetime { ident: name.into() }; - - self.bounds.push(lifetime); - self - } - - pub fn build(self) -> F::Result { - self.callback.invoke(LifetimeDef { - attrs: vec![], - lifetime: self.lifetime, - bounds: self.bounds, - }) - } -} diff --git a/third_party/rust/syn-0.10.8/src/aster/mod.rs b/third_party/rust/syn-0.10.8/src/aster/mod.rs deleted file mode 100644 index 9e30e2289c6b..000000000000 --- a/third_party/rust/syn-0.10.8/src/aster/mod.rs +++ /dev/null @@ -1,33 +0,0 @@ -use super::*; - -pub mod generics; -pub mod ident; -pub mod invoke; -pub mod lifetime; -pub mod path; -pub mod qpath; -pub mod ty; -pub mod ty_param; -pub mod where_predicate; - -pub fn id(id: I) -> Ident - where I: Into -{ - id.into() -} - -pub fn from_generics(generics: Generics) -> generics::GenericsBuilder { - generics::GenericsBuilder::from_generics(generics) -} - -pub fn where_predicate() -> where_predicate::WherePredicateBuilder { - where_predicate::WherePredicateBuilder::new() -} - -pub fn ty() -> ty::TyBuilder { - ty::TyBuilder::new() -} - -pub fn path() -> path::PathBuilder { - path::PathBuilder::new() -} diff --git a/third_party/rust/syn-0.10.8/src/aster/path.rs b/third_party/rust/syn-0.10.8/src/aster/path.rs deleted file mode 100644 index a0fb314384ec..000000000000 --- a/third_party/rust/syn-0.10.8/src/aster/path.rs +++ /dev/null @@ -1,331 +0,0 @@ -use {AngleBracketedParameterData, Generics, Ident, Lifetime, ParenthesizedParameterData, Path, - PathParameters, PathSegment, Ty, TypeBinding}; -use aster::ident::ToIdent; -use aster::invoke::{Invoke, Identity}; -use aster::lifetime::IntoLifetime; -use aster::ty::TyBuilder; - -// //////////////////////////////////////////////////////////////////////////// - -pub trait IntoPath { - fn into_path(self) -> Path; -} - -impl IntoPath for Path { - fn into_path(self) -> Path { - self - } -} - -impl IntoPath for Ident { - fn into_path(self) -> Path { - PathBuilder::new().id(self).build() - } -} - -impl<'a> IntoPath for &'a str { - fn into_path(self) -> Path { - PathBuilder::new().id(self).build() - } -} - -impl IntoPath for String { - fn into_path(self) -> Path { - (&*self).into_path() - } -} - -impl<'a, T> IntoPath for &'a [T] - where T: ToIdent -{ - fn into_path(self) -> Path { - PathBuilder::new().ids(self).build() - } -} - -// //////////////////////////////////////////////////////////////////////////// - -pub struct PathBuilder { - callback: F, - global: bool, -} - -impl PathBuilder { - pub fn new() -> Self { - PathBuilder::with_callback(Identity) - } -} - -impl PathBuilder - where F: Invoke -{ - pub fn with_callback(callback: F) -> Self { - PathBuilder { - callback: callback, - global: false, - } - } - - pub fn build(self, path: Path) -> F::Result { - self.callback.invoke(path) - } - - pub fn global(mut self) -> Self { - self.global = true; - self - } - - pub fn ids(self, ids: I) -> PathSegmentsBuilder - where I: IntoIterator, - T: ToIdent - { - let mut ids = ids.into_iter(); - let id = ids.next().expect("passed path with no id"); - - self.id(id).ids(ids) - } - - pub fn id(self, id: I) -> PathSegmentsBuilder - where I: ToIdent - { - self.segment(id).build() - } - - pub fn segment(self, id: I) -> PathSegmentBuilder> - where I: ToIdent - { - PathSegmentBuilder::with_callback(id, - PathSegmentsBuilder { - callback: self.callback, - global: self.global, - segments: Vec::new(), - }) - } -} - -// //////////////////////////////////////////////////////////////////////////// - -pub struct PathSegmentsBuilder { - callback: F, - global: bool, - segments: Vec, -} - -impl PathSegmentsBuilder - where F: Invoke -{ - pub fn ids(mut self, ids: I) -> PathSegmentsBuilder - where I: IntoIterator, - T: ToIdent - { - for id in ids { - self = self.id(id); - } - - self - } - - pub fn id(self, id: T) -> PathSegmentsBuilder - where T: ToIdent - { - self.segment(id).build() - } - - pub fn segment(self, id: T) -> PathSegmentBuilder - where T: ToIdent - { - PathSegmentBuilder::with_callback(id, self) - } - - pub fn build(self) -> F::Result { - self.callback.invoke(Path { - global: self.global, - segments: self.segments, - }) - } -} - -impl Invoke for PathSegmentsBuilder { - type Result = Self; - - fn invoke(mut self, segment: PathSegment) -> Self { - self.segments.push(segment); - self - } -} - -// //////////////////////////////////////////////////////////////////////////// - -pub struct PathSegmentBuilder { - callback: F, - id: Ident, - lifetimes: Vec, - tys: Vec, - bindings: Vec, -} - -impl PathSegmentBuilder - where F: Invoke -{ - pub fn with_callback(id: I, callback: F) -> Self - where I: ToIdent - { - PathSegmentBuilder { - callback: callback, - id: id.to_ident(), - lifetimes: Vec::new(), - tys: Vec::new(), - bindings: Vec::new(), - } - } - - pub fn with_generics(self, generics: Generics) -> Self { - // Strip off the bounds. - let lifetimes = generics.lifetimes - .iter() - .map(|lifetime_def| lifetime_def.lifetime.clone()); - - let tys = generics.ty_params - .iter() - .map(|ty_param| TyBuilder::new().id(ty_param.ident.clone())); - - self.with_lifetimes(lifetimes) - .with_tys(tys) - } - - pub fn with_lifetimes(mut self, iter: I) -> Self - where I: IntoIterator, - L: IntoLifetime - { - let iter = iter.into_iter().map(|lifetime| lifetime.into_lifetime()); - self.lifetimes.extend(iter); - self - } - - pub fn with_lifetime(mut self, lifetime: L) -> Self - where L: IntoLifetime - { - self.lifetimes.push(lifetime.into_lifetime()); - self - } - - pub fn lifetime(self, name: N) -> Self - where N: ToIdent - { - let lifetime = Lifetime { ident: name.to_ident() }; - self.with_lifetime(lifetime) - } - - pub fn with_tys(mut self, iter: I) -> Self - where I: IntoIterator - { - self.tys.extend(iter); - self - } - - pub fn with_ty(mut self, ty: Ty) -> Self { - self.tys.push(ty); - self - } - - pub fn ty(self) -> TyBuilder { - TyBuilder::with_callback(self) - } - - pub fn with_binding(mut self, binding: TypeBinding) -> Self { - self.bindings.push(binding); - self - } - - pub fn binding(self, id: T) -> TyBuilder> - where T: ToIdent - { - TyBuilder::with_callback(TypeBindingBuilder { - id: id.to_ident(), - builder: self, - }) - } - - pub fn no_return(self) -> F::Result { - self.build_return(None) - } - - pub fn return_(self) -> TyBuilder> { - TyBuilder::with_callback(PathSegmentReturnBuilder(self)) - } - - pub fn build_return(self, output: Option) -> F::Result { - let data = ParenthesizedParameterData { - inputs: self.tys, - output: output, - }; - - let parameters = PathParameters::Parenthesized(data); - - self.callback.invoke(PathSegment { - ident: self.id, - parameters: parameters, - }) - } - - pub fn build(self) -> F::Result { - let data = AngleBracketedParameterData { - lifetimes: self.lifetimes, - types: self.tys, - bindings: self.bindings, - }; - - let parameters = PathParameters::AngleBracketed(data); - - self.callback.invoke(PathSegment { - ident: self.id, - parameters: parameters, - }) - } -} - -impl Invoke for PathSegmentBuilder - where F: Invoke -{ - type Result = Self; - - fn invoke(self, ty: Ty) -> Self { - self.with_ty(ty) - } -} - -// //////////////////////////////////////////////////////////////////////////// - -pub struct TypeBindingBuilder { - id: Ident, - builder: PathSegmentBuilder, -} - -impl Invoke for TypeBindingBuilder - where F: Invoke -{ - type Result = PathSegmentBuilder; - - fn invoke(self, ty: Ty) -> Self::Result { - let id = self.id; - - self.builder.with_binding(TypeBinding { - ident: id, - ty: ty, - }) - } -} - -// //////////////////////////////////////////////////////////////////////////// - -pub struct PathSegmentReturnBuilder(PathSegmentBuilder); - -impl Invoke for PathSegmentReturnBuilder - where F: Invoke -{ - type Result = F::Result; - - fn invoke(self, ty: Ty) -> Self::Result { - self.0.build_return(Some(ty)) - } -} diff --git a/third_party/rust/syn-0.10.8/src/aster/qpath.rs b/third_party/rust/syn-0.10.8/src/aster/qpath.rs deleted file mode 100644 index 6ecde8609b62..000000000000 --- a/third_party/rust/syn-0.10.8/src/aster/qpath.rs +++ /dev/null @@ -1,146 +0,0 @@ -use {Path, PathSegment, QSelf, Ty}; -use aster::ident::ToIdent; -use aster::invoke::{Invoke, Identity}; -use aster::path::{PathBuilder, PathSegmentBuilder}; -use aster::ty::TyBuilder; - -// //////////////////////////////////////////////////////////////////////////// - -pub struct QPathBuilder { - callback: F, -} - -impl QPathBuilder { - pub fn new() -> Self { - QPathBuilder::with_callback(Identity) - } -} - -impl QPathBuilder - where F: Invoke<(QSelf, Path)> -{ - /// Construct a `QPathBuilder` that will call the `callback` with a constructed `QSelf` - /// and `Path`. - pub fn with_callback(callback: F) -> Self { - QPathBuilder { callback: callback } - } - - /// Build a qualified path first by starting with a type builder. - pub fn with_ty(self, ty: Ty) -> QPathTyBuilder { - QPathTyBuilder { - builder: self, - ty: ty, - } - } - - /// Build a qualified path first by starting with a type builder. - pub fn ty(self) -> TyBuilder { - TyBuilder::with_callback(self) - } - - /// Build a qualified path with a concrete type and path. - pub fn build(self, qself: QSelf, path: Path) -> F::Result { - self.callback.invoke((qself, path)) - } -} - -impl Invoke for QPathBuilder - where F: Invoke<(QSelf, Path)> -{ - type Result = QPathTyBuilder; - - fn invoke(self, ty: Ty) -> QPathTyBuilder { - self.with_ty(ty) - } -} - -// //////////////////////////////////////////////////////////////////////////// - -pub struct QPathTyBuilder { - builder: QPathBuilder, - ty: Ty, -} - -impl QPathTyBuilder - where F: Invoke<(QSelf, Path)> -{ - /// Build a qualified path with a path builder. - // Clippy false positive - // https://github.com/Manishearth/rust-clippy/issues/1285 - #[cfg_attr(feature = "clippy", allow(wrong_self_convention))] - pub fn as_(self) -> PathBuilder { - PathBuilder::with_callback(self) - } - - pub fn id(self, id: T) -> F::Result - where T: ToIdent - { - let path = Path { - global: false, - segments: vec![], - }; - self.as_().build(path).id(id) - } - - pub fn segment(self, id: T) -> PathSegmentBuilder> - where T: ToIdent - { - let path = Path { - global: false, - segments: vec![], - }; - self.as_().build(path).segment(id) - } -} - -impl Invoke for QPathTyBuilder - where F: Invoke<(QSelf, Path)> -{ - type Result = QPathQSelfBuilder; - - fn invoke(self, path: Path) -> QPathQSelfBuilder { - QPathQSelfBuilder { - builder: self.builder, - qself: QSelf { - ty: Box::new(self.ty), - position: path.segments.len(), - }, - path: path, - } - } -} - -// //////////////////////////////////////////////////////////////////////////// - -pub struct QPathQSelfBuilder { - builder: QPathBuilder, - qself: QSelf, - path: Path, -} - -impl QPathQSelfBuilder - where F: Invoke<(QSelf, Path)> -{ - pub fn id(self, id: T) -> F::Result - where T: ToIdent - { - self.segment(id).build() - } - - pub fn segment(self, id: T) -> PathSegmentBuilder> - where T: ToIdent - { - PathSegmentBuilder::with_callback(id, self) - } -} - -impl Invoke for QPathQSelfBuilder - where F: Invoke<(QSelf, Path)> -{ - type Result = F::Result; - - fn invoke(mut self, segment: PathSegment) -> F::Result { - self.path.segments.push(segment); - self.builder.build(self.qself, self.path) - } -} diff --git a/third_party/rust/syn-0.10.8/src/aster/ty.rs b/third_party/rust/syn-0.10.8/src/aster/ty.rs deleted file mode 100644 index 96b6554d20c1..000000000000 --- a/third_party/rust/syn-0.10.8/src/aster/ty.rs +++ /dev/null @@ -1,578 +0,0 @@ -use {Generics, Lifetime, MutTy, Mutability, Path, QSelf, Ty, TyParamBound}; -use aster::ident::ToIdent; -use aster::invoke::{Invoke, Identity}; -use aster::lifetime::IntoLifetime; -use aster::path::PathBuilder; -use aster::qpath::QPathBuilder; -use aster::ty_param::TyParamBoundBuilder; - -// //////////////////////////////////////////////////////////////////////////// - -pub struct TyBuilder { - callback: F, -} - -impl TyBuilder { - pub fn new() -> Self { - TyBuilder::with_callback(Identity) - } -} - -impl TyBuilder - where F: Invoke -{ - pub fn with_callback(callback: F) -> Self { - TyBuilder { callback: callback } - } - - pub fn build(self, ty: Ty) -> F::Result { - self.callback.invoke(ty) - } - - pub fn id(self, id: I) -> F::Result - where I: ToIdent - { - self.path().id(id).build() - } - - pub fn build_path(self, path: Path) -> F::Result { - self.build(Ty::Path(None, path)) - } - - pub fn build_qpath(self, qself: QSelf, path: Path) -> F::Result { - self.build(Ty::Path(Some(qself), path)) - } - - pub fn path(self) -> PathBuilder> { - PathBuilder::with_callback(TyPathBuilder(self)) - } - - pub fn qpath(self) -> QPathBuilder> { - QPathBuilder::with_callback(TyQPathBuilder(self)) - } - - pub fn isize(self) -> F::Result { - self.id("isize") - } - - pub fn i8(self) -> F::Result { - self.id("i8") - } - - pub fn i16(self) -> F::Result { - self.id("i16") - } - - pub fn i32(self) -> F::Result { - self.id("i32") - } - - pub fn i64(self) -> F::Result { - self.id("i64") - } - - pub fn usize(self) -> F::Result { - self.id("usize") - } - - pub fn u8(self) -> F::Result { - self.id("u8") - } - - pub fn u16(self) -> F::Result { - self.id("u16") - } - - pub fn u32(self) -> F::Result { - self.id("u32") - } - - pub fn u64(self) -> F::Result { - self.id("u64") - } - - pub fn f32(self) -> F::Result { - self.id("f32") - } - - pub fn f64(self) -> F::Result { - self.id("f64") - } - - pub fn bool(self) -> F::Result { - self.id("bool") - } - - pub fn unit(self) -> F::Result { - self.tuple().build() - } - - pub fn tuple(self) -> TyTupleBuilder { - TyTupleBuilder { - builder: self, - tys: vec![], - } - } - - pub fn build_slice(self, ty: Ty) -> F::Result { - self.build(Ty::Slice(Box::new(ty))) - } - - pub fn slice(self) -> TyBuilder> { - TyBuilder::with_callback(TySliceBuilder(self)) - } - - pub fn ref_(self) -> TyRefBuilder { - TyRefBuilder { - builder: self, - lifetime: None, - mutability: Mutability::Immutable, - } - } - - pub fn never(self) -> F::Result { - self.build(Ty::Never) - } - - pub fn infer(self) -> F::Result { - self.build(Ty::Infer) - } - - pub fn option(self) -> TyBuilder> { - TyBuilder::with_callback(TyOptionBuilder(self)) - } - - pub fn result(self) -> TyBuilder> { - TyBuilder::with_callback(TyResultOkBuilder(self)) - } - - pub fn phantom_data(self) -> TyBuilder> { - TyBuilder::with_callback(TyPhantomDataBuilder(self)) - } - - pub fn box_(self) -> TyBuilder> { - TyBuilder::with_callback(TyBoxBuilder(self)) - } - - pub fn iterator(self) -> TyBuilder> { - TyBuilder::with_callback(TyIteratorBuilder(self)) - } - - pub fn object_sum(self) -> TyBuilder> { - TyBuilder::with_callback(TyObjectSumBuilder { builder: self }) - } - - pub fn impl_trait(self) -> TyImplTraitTyBuilder { - TyImplTraitTyBuilder { - builder: self, - bounds: Vec::new(), - } - } -} - -// //////////////////////////////////////////////////////////////////////////// - -pub struct TyPathBuilder(TyBuilder); - -impl Invoke for TyPathBuilder - where F: Invoke -{ - type Result = F::Result; - - fn invoke(self, path: Path) -> F::Result { - self.0.build_path(path) - } -} - -// //////////////////////////////////////////////////////////////////////////// - -pub struct TyQPathBuilder(TyBuilder); - -impl Invoke<(QSelf, Path)> for TyQPathBuilder - where F: Invoke -{ - type Result = F::Result; - - fn invoke(self, (qself, path): (QSelf, Path)) -> F::Result { - self.0.build_qpath(qself, path) - } -} - -// //////////////////////////////////////////////////////////////////////////// - -pub struct TySliceBuilder(TyBuilder); - -impl Invoke for TySliceBuilder - where F: Invoke -{ - type Result = F::Result; - - fn invoke(self, ty: Ty) -> F::Result { - self.0.build_slice(ty) - } -} - -// //////////////////////////////////////////////////////////////////////////// - -pub struct TyRefBuilder { - builder: TyBuilder, - lifetime: Option, - mutability: Mutability, -} - -impl TyRefBuilder - where F: Invoke -{ - pub fn mut_(mut self) -> Self { - self.mutability = Mutability::Mutable; - self - } - - pub fn lifetime(mut self, name: N) -> Self - where N: ToIdent - { - self.lifetime = Some(Lifetime { ident: name.to_ident() }); - self - } - - pub fn build_ty(self, ty: Ty) -> F::Result { - let ty = MutTy { - ty: ty, - mutability: self.mutability, - }; - self.builder.build(Ty::Rptr(self.lifetime, Box::new(ty))) - } - - pub fn ty(self) -> TyBuilder { - TyBuilder::with_callback(self) - } -} - -impl Invoke for TyRefBuilder - where F: Invoke -{ - type Result = F::Result; - - fn invoke(self, ty: Ty) -> F::Result { - self.build_ty(ty) - } -} - -// //////////////////////////////////////////////////////////////////////////// - -pub struct TyOptionBuilder(TyBuilder); - -impl Invoke for TyOptionBuilder - where F: Invoke -{ - type Result = F::Result; - - fn invoke(self, ty: Ty) -> F::Result { - let path = PathBuilder::new() - .global() - .id("std") - .id("option") - .segment("Option") - .with_ty(ty) - .build() - .build(); - - self.0.build_path(path) - } -} - -// //////////////////////////////////////////////////////////////////////////// - -pub struct TyResultOkBuilder(TyBuilder); - -impl Invoke for TyResultOkBuilder - where F: Invoke -{ - type Result = TyBuilder>; - - fn invoke(self, ty: Ty) -> TyBuilder> { - TyBuilder::with_callback(TyResultErrBuilder(self.0, ty)) - } -} - -pub struct TyResultErrBuilder(TyBuilder, Ty); - -impl Invoke for TyResultErrBuilder - where F: Invoke -{ - type Result = F::Result; - - fn invoke(self, ty: Ty) -> F::Result { - let path = PathBuilder::new() - .global() - .id("std") - .id("result") - .segment("Result") - .with_ty(self.1) - .with_ty(ty) - .build() - .build(); - - self.0.build_path(path) - } -} - -// //////////////////////////////////////////////////////////////////////////// - -pub struct TyPhantomDataBuilder(TyBuilder); - -impl Invoke for TyPhantomDataBuilder - where F: Invoke -{ - type Result = F::Result; - - fn invoke(self, ty: Ty) -> F::Result { - let path = PathBuilder::new() - .global() - .id("std") - .id("marker") - .segment("PhantomData") - .with_ty(ty) - .build() - .build(); - - self.0.build_path(path) - } -} - -// //////////////////////////////////////////////////////////////////////////// - -pub struct TyBoxBuilder(TyBuilder); - -impl Invoke for TyBoxBuilder - where F: Invoke -{ - type Result = F::Result; - - fn invoke(self, ty: Ty) -> F::Result { - let path = PathBuilder::new() - .global() - .id("std") - .id("boxed") - .segment("Box") - .with_ty(ty) - .build() - .build(); - - self.0.build_path(path) - } -} - -// //////////////////////////////////////////////////////////////////////////// - -pub struct TyIteratorBuilder(TyBuilder); - -impl Invoke for TyIteratorBuilder - where F: Invoke -{ - type Result = F::Result; - - fn invoke(self, ty: Ty) -> F::Result { - let path = PathBuilder::new() - .global() - .id("std") - .id("iter") - .segment("Iterator") - .binding("Item") - .build(ty.clone()) - .build() - .build(); - - self.0.build_path(path) - } -} - -// //////////////////////////////////////////////////////////////////////////// - -pub struct TyObjectSumBuilder { - builder: TyBuilder, -} - -impl Invoke for TyObjectSumBuilder - where F: Invoke -{ - type Result = TyObjectSumTyBuilder; - - fn invoke(self, ty: Ty) -> Self::Result { - TyObjectSumTyBuilder { - builder: self.builder, - ty: ty, - bounds: Vec::new(), - } - } -} - -pub struct TyObjectSumTyBuilder { - builder: TyBuilder, - ty: Ty, - bounds: Vec, -} - -impl TyObjectSumTyBuilder - where F: Invoke -{ - pub fn with_bounds(mut self, iter: I) -> Self - where I: Iterator - { - self.bounds.extend(iter); - self - } - - pub fn with_bound(mut self, bound: TyParamBound) -> Self { - self.bounds.push(bound); - self - } - - pub fn bound(self) -> TyParamBoundBuilder { - TyParamBoundBuilder::with_callback(self) - } - - pub fn with_generics(self, generics: Generics) -> Self { - self.with_lifetimes(generics.lifetimes - .into_iter() - .map(|def| def.lifetime)) - } - - pub fn with_lifetimes(mut self, lifetimes: I) -> Self - where I: Iterator, - L: IntoLifetime - { - for lifetime in lifetimes { - self = self.lifetime(lifetime); - } - - self - } - - pub fn lifetime(self, lifetime: L) -> Self - where L: IntoLifetime - { - self.bound().lifetime(lifetime) - } - - pub fn build(self) -> F::Result { - let bounds = self.bounds; - self.builder.build(Ty::ObjectSum(Box::new(self.ty), bounds)) - } -} - -impl Invoke for TyObjectSumTyBuilder - where F: Invoke -{ - type Result = Self; - - fn invoke(self, bound: TyParamBound) -> Self { - self.with_bound(bound) - } -} - -// //////////////////////////////////////////////////////////////////////////// - -pub struct TyImplTraitTyBuilder { - builder: TyBuilder, - bounds: Vec, -} - -impl TyImplTraitTyBuilder - where F: Invoke -{ - pub fn with_bounds(mut self, iter: I) -> Self - where I: Iterator - { - self.bounds.extend(iter); - self - } - - pub fn with_bound(mut self, bound: TyParamBound) -> Self { - self.bounds.push(bound); - self - } - - pub fn bound(self) -> TyParamBoundBuilder { - TyParamBoundBuilder::with_callback(self) - } - - pub fn with_generics(self, generics: Generics) -> Self { - self.with_lifetimes(generics.lifetimes - .into_iter() - .map(|def| def.lifetime)) - } - - pub fn with_lifetimes(mut self, lifetimes: I) -> Self - where I: Iterator, - L: IntoLifetime - { - for lifetime in lifetimes { - self = self.lifetime(lifetime); - } - - self - } - - pub fn lifetime(self, lifetime: L) -> Self - where L: IntoLifetime - { - self.bound().lifetime(lifetime) - } - - pub fn build(self) -> F::Result { - let bounds = self.bounds; - self.builder.build(Ty::ImplTrait(bounds)) - } -} - -impl Invoke for TyImplTraitTyBuilder - where F: Invoke -{ - type Result = Self; - - fn invoke(self, bound: TyParamBound) -> Self { - self.with_bound(bound) - } -} - -// //////////////////////////////////////////////////////////////////////////// - -pub struct TyTupleBuilder { - builder: TyBuilder, - tys: Vec, -} - -impl TyTupleBuilder - where F: Invoke -{ - pub fn with_tys(mut self, iter: I) -> Self - where I: IntoIterator - { - self.tys.extend(iter); - self - } - - pub fn with_ty(mut self, ty: Ty) -> Self { - self.tys.push(ty); - self - } - - pub fn ty(self) -> TyBuilder { - TyBuilder::with_callback(self) - } - - pub fn build(self) -> F::Result { - self.builder.build(Ty::Tup(self.tys)) - } -} - -impl Invoke for TyTupleBuilder - where F: Invoke -{ - type Result = Self; - - fn invoke(self, ty: Ty) -> Self { - self.with_ty(ty) - } -} diff --git a/third_party/rust/syn-0.10.8/src/aster/ty_param.rs b/third_party/rust/syn-0.10.8/src/aster/ty_param.rs deleted file mode 100644 index 2836203bec78..000000000000 --- a/third_party/rust/syn-0.10.8/src/aster/ty_param.rs +++ /dev/null @@ -1,262 +0,0 @@ -use {Ident, LifetimeDef, Path, PolyTraitRef, TraitBoundModifier, Ty, TyParam, TyParamBound}; -use aster::invoke::{Invoke, Identity}; -use aster::lifetime::{IntoLifetime, IntoLifetimeDef, LifetimeDefBuilder}; -use aster::path::{IntoPath, PathBuilder}; -use aster::ty::TyBuilder; - -// //////////////////////////////////////////////////////////////////////////// - -pub struct TyParamBuilder { - callback: F, - id: Ident, - bounds: Vec, - default: Option, -} - -impl TyParamBuilder { - pub fn new(id: I) -> Self - where I: Into - { - TyParamBuilder::with_callback(id, Identity) - } - - pub fn from_ty_param(ty_param: TyParam) -> Self { - TyParamBuilder::from_ty_param_with_callback(Identity, ty_param) - } -} - -impl TyParamBuilder - where F: Invoke -{ - pub fn with_callback(id: I, callback: F) -> Self - where I: Into - { - TyParamBuilder { - callback: callback, - id: id.into(), - bounds: Vec::new(), - default: None, - } - } - - pub fn from_ty_param_with_callback(callback: F, ty_param: TyParam) -> Self { - TyParamBuilder { - callback: callback, - id: ty_param.ident, - bounds: ty_param.bounds, - default: ty_param.default, - } - } - - pub fn with_default(mut self, ty: Ty) -> Self { - self.default = Some(ty); - self - } - - pub fn default(self) -> TyBuilder { - TyBuilder::with_callback(self) - } - - pub fn with_bound(mut self, bound: TyParamBound) -> Self { - self.bounds.push(bound); - self - } - - pub fn bound(self) -> TyParamBoundBuilder { - TyParamBoundBuilder::with_callback(self) - } - - pub fn with_trait_bound(self, trait_ref: PolyTraitRef) -> Self { - self.bound().build_trait(trait_ref, TraitBoundModifier::None) - } - - pub fn trait_bound