aboutsummaryrefslogtreecommitdiffstats
path: root/components/script_plugins/webidl_must_inherit.rs
diff options
context:
space:
mode:
authorkrk <keremkat@gmail.com>2019-04-14 14:16:38 +0200
committerkrk <keremkat@gmail.com>2019-04-20 22:39:22 +0200
commitdfca8ec913dd77cc07a9cc2053047f0d6bd09ed6 (patch)
tree123157223b289fa1ac6ee6f4fce7426a253ee8e7 /components/script_plugins/webidl_must_inherit.rs
parent328244684a8b1f98d515d5f40655b9cf7347affd (diff)
downloadservo-dfca8ec913dd77cc07a9cc2053047f0d6bd09ed6.tar.gz
servo-dfca8ec913dd77cc07a9cc2053047f0d6bd09ed6.zip
Can collect webidl paths.
Diffstat (limited to 'components/script_plugins/webidl_must_inherit.rs')
-rw-r--r--components/script_plugins/webidl_must_inherit.rs133
1 files changed, 133 insertions, 0 deletions
diff --git a/components/script_plugins/webidl_must_inherit.rs b/components/script_plugins/webidl_must_inherit.rs
new file mode 100644
index 00000000000..96ef9e75db2
--- /dev/null
+++ b/components/script_plugins/webidl_must_inherit.rs
@@ -0,0 +1,133 @@
+/* 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 https://mozilla.org/MPL/2.0/. */
+
+use rustc::hir::{self, HirId};
+use rustc::lint::{LateContext, LateLintPass, LintArray, LintContext, LintPass};
+use rustc::ty;
+use std::env;
+
+use std::io;
+use std::path;
+use syntax::ast;
+declare_lint!(
+ WEBIDL_INHERIT_CORRECT,
+ Deny,
+ "Warn and report usage of incorrect webidl inheritance"
+);
+
+pub struct WebIdlPass;
+
+impl WebIdlPass {
+ pub fn new() -> WebIdlPass {
+ WebIdlPass
+ }
+}
+
+fn get_typ_name(typ: String) -> Option<String> {
+ if let Some(i) = typ.rfind(':') {
+ return Some(typ[i + 1..].to_string());
+ }
+ None
+}
+
+fn get_webidl_path(struct_name: &str) -> io::Result<path::PathBuf> {
+ let mut dir = env::current_dir()?;
+ dir.push("components/script/dom/webidls/");
+ dir.push(format!("{}.webidl", struct_name));
+
+ return Ok(dir);
+}
+
+/// Checks if a type is unrooted or contains any owned unrooted types
+fn is_webidl_ty(cx: &LateContext, ty: &ty::TyS) -> bool {
+ let mut ret = false;
+ ty.maybe_walk(|t| {
+ match t.sty {
+ ty::Adt(did, _substs) => {
+ if cx.tcx.has_attr(did.did, "webidl") {
+ ret = true;
+ }
+ false
+ },
+ ty::Ref(..) => false, // don't recurse down &ptrs
+ ty::RawPtr(..) => false, // don't recurse down *ptrs
+ ty::FnDef(..) | ty::FnPtr(_) => false,
+ _ => true,
+ }
+ });
+ ret
+}
+
+fn check_webidl(name: &str, parent_name: Option<String>) -> io::Result<()> {
+ let path = get_webidl_path(&name)?;
+ println!("struct_webidl_path: {:?}", &path);
+
+ if let Some(parent) = parent_name {
+ let parent_path = get_webidl_path(&parent)?;
+ println!("parent_path: {:?}", &parent_path);
+ }
+
+ Ok(())
+}
+
+impl LintPass for WebIdlPass {
+ fn name(&self) -> &'static str {
+ "ServoWebIDLPass"
+ }
+
+ fn get_lints(&self) -> LintArray {
+ lint_array!(WEBIDL_INHERIT_CORRECT)
+ }
+}
+
+impl<'a, 'tcx> LateLintPass<'a, 'tcx> for WebIdlPass {
+ fn check_struct_def(
+ &mut self,
+ cx: &LateContext<'a, 'tcx>,
+ def: &'tcx hir::VariantData,
+ n: ast::Name,
+ _gen: &'tcx hir::Generics,
+ id: HirId,
+ ) {
+ let def_id = cx.tcx.hir().local_def_id_from_hir_id(id);
+ if !is_webidl_ty(cx, cx.tcx.type_of(def_id)) {
+ return;
+ }
+
+ let item = match cx.tcx.hir().get_by_hir_id(id) {
+ hir::Node::Item(item) => item,
+ _ => cx
+ .tcx
+ .hir()
+ .expect_item_by_hir_id(cx.tcx.hir().get_parent_item(id)),
+ };
+
+ let struct_name = n.to_string();
+ println!("struct_name: {:?}", struct_name);
+
+ let mut parent_typ_name: Option<String> = None;
+ for ref field in def.fields() {
+ let def_id = cx.tcx.hir().local_def_id_from_hir_id(field.hir_id);
+ let ty = cx.tcx.type_of(def_id);
+ let typ = ty.to_string();
+ if let Some(typ_name) = get_typ_name(ty.to_string()) {
+ parent_typ_name = Some(typ_name);
+ break;
+ } else {
+ cx.span_lint(WEBIDL_INHERIT_CORRECT, field.span, "Cannot get type name");
+ }
+
+ // Only first field is relevant.
+ break;
+ }
+
+ // TODO Open and parse corresponding webidl file.
+ cx.span_lint(WEBIDL_INHERIT_CORRECT, item.ident.span, "WEBIDL present.");
+
+ match check_webidl(&struct_name, parent_typ_name) {
+ Ok(()) => {},
+ Err(e) => println!("ERRORRR: {:?}", e),
+ };
+ }
+}