Skip to content

Commit

Permalink
Tests: Add tests for ClangPlugin's macro validation
Browse files Browse the repository at this point in the history
  • Loading branch information
mattco98 authored and ADKaster committed May 30, 2024
1 parent 36d032b commit f860763
Show file tree
Hide file tree
Showing 6 changed files with 260 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* Copyright (c) 2024, Matthew Olsson <mattco@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/

// RUN: %clang++ -cc1 -verify %plugin_opts% %s 2>&1

#include <LibJS/Runtime/PrototypeObject.h>
#include <LibWeb/Bindings/PlatformObject.h>

// expected-error@+1 {{Expected record to have a JS_CELL macro invocation}}
class TestCellClass : JS::Cell {
};

// expected-error@+1 {{Expected record to have a JS_OBJECT macro invocation}}
class TestObjectClass : JS::Object {
};

// expected-error@+1 {{Expected record to have a JS_ENVIRONMENT macro invocation}}
class TestEnvironmentClass : JS::Environment {
};

// expected-error@+1 {{Expected record to have a JS_PROTOTYPE_OBJECT macro invocation}}
class TestPrototypeClass : JS::PrototypeObject<TestCellClass, TestCellClass> {
};

// expected-error@+1 {{Expected record to have a WEB_PLATFORM_OBJECT macro invocation}}
class TestPlatformClass : Web::Bindings::PlatformObject {
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*
* Copyright (c) 2024, Matthew Olsson <mattco@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/

// RUN: %clang++ -cc1 -verify %plugin_opts% %s 2>&1
// expected-no-diagnostics

#include <LibJS/Runtime/PrototypeObject.h>
#include <LibWeb/Bindings/PlatformObject.h>

class TestCellClass : JS::Cell {
JS_CELL(TestCellClass, JS::Cell);
};

class TestObjectClass : JS::Object {
JS_OBJECT(TestObjectClass, JS::Object);
};

class TestEnvironmentClass : JS::Environment {
JS_ENVIRONMENT(TestEnvironmentClass, JS::Environment);
};

class TestPlatformClass : Web::Bindings::PlatformObject {
WEB_PLATFORM_OBJECT(TestPlatformClass, Web::Bindings::PlatformObject);
};

namespace JS {

class TestPrototypeClass : JS::PrototypeObject<TestCellClass, TestCellClass> {
JS_PROTOTYPE_OBJECT(TestPrototypeClass, TestCellClass, TestCellClass);
};

}

// Nested classes
class Parent1 { };
class Parent2 : JS::Cell {
JS_CELL(Parent2, JS::Cell);
};
class Parent3 { };
class Parent4 : public Parent2 {
JS_CELL(Parent4, Parent2);
};

class NestedCellClass
: Parent1
, Parent3
, Parent4 {
JS_CELL(NestedCellClass, Parent4); // Not Parent2
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
* Copyright (c) 2024, Matthew Olsson <mattco@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/

// RUN: %clang++ -cc1 -verify %plugin_opts% %s 2>&1

#include <LibJS/Runtime/Object.h>
#include <LibJS/Runtime/PrototypeObject.h>

// Note: Using WEB_PLATFORM_OBJECT() on a class that doesn't inherit from Web::Bindings::PlatformObject
// is a compilation error, so that is not tested here.
// Note: It's pretty hard to have the incorrect type in a JS::PrototypeObject, since the base name would
// have a comma in it, and wouldn't be passable as the basename without a typedef.

class CellWithObjectMacro : JS::Cell {
// expected-error@+1 {{Invalid JS-CELL-like macro invocation; expected JS_CELL}}
JS_OBJECT(CellWithObjectMacro, JS::Cell);
};

class CellWithEnvironmentMacro : JS::Cell {
// expected-error@+1 {{Invalid JS-CELL-like macro invocation; expected JS_CELL}}
JS_ENVIRONMENT(CellWithEnvironmentMacro, JS::Cell);
};

class ObjectWithCellMacro : JS::Object {
// expected-error@+1 {{Invalid JS-CELL-like macro invocation; expected JS_OBJECT}}
JS_CELL(ObjectWithCellMacro, JS::Object);
};

class ObjectWithEnvironmentMacro : JS::Object {
// expected-error@+1 {{Invalid JS-CELL-like macro invocation; expected JS_OBJECT}}
JS_ENVIRONMENT(ObjectWithEnvironmentMacro, JS::Object);
};

// JS_PROTOTYPE_OBJECT can only be used in the JS namespace
namespace JS {

class CellWithPrototypeMacro : Cell {
// expected-error@+1 {{Invalid JS-CELL-like macro invocation; expected JS_CELL}}
JS_PROTOTYPE_OBJECT(CellWithPrototypeMacro, Cell, Cell);
};

class ObjectWithPrototypeMacro : Object {
// expected-error@+1 {{Invalid JS-CELL-like macro invocation; expected JS_OBJECT}}
JS_PROTOTYPE_OBJECT(ObjectWithPrototypeMacro, Object, Object);
};

}
38 changes: 38 additions & 0 deletions Tests/ClangPlugins/LibJSGCTests/Macros/nested_macros.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
* Copyright (c) 2024, Matthew Olsson <mattco@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/

// RUN: %clang++ -cc1 -verify %plugin_opts% %s 2>&1

#include <LibJS/Runtime/Object.h>

class TestClass : JS::Object {
JS_OBJECT(TestClass, JS::Object);

struct NestedClassOk : JS::Cell {
JS_CELL(NestedClassOk, JS::Cell);
};

// expected-error@+1 {{Expected record to have a JS_OBJECT macro invocation}}
struct NestedClassBad : JS::Object {
};

struct NestedClassNonCell {
};
};

// Same test, but the parent object is not a cell
class TestClass2 {
struct NestedClassOk : JS::Cell {
JS_CELL(NestedClassOk, JS::Cell);
};

// expected-error@+1 {{Expected record to have a JS_OBJECT macro invocation}}
struct NestedClassBad : JS::Object {
};

struct NestedClassNonCell {
};
};
49 changes: 49 additions & 0 deletions Tests/ClangPlugins/LibJSGCTests/Macros/wrong_basename_arg.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
* Copyright (c) 2024, Matthew Olsson <mattco@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/

// RUN: %clang++ -cc1 -verify %plugin_opts% %s 2>&1

#include <LibJS/Runtime/Object.h>

// The only way to have an incorrect basename is if the class is deeply nested, and the base name
// refers to a parent class

class ParentObject : JS::Object {
JS_OBJECT(ParentObject, JS::Object);
};

class TestClass : ParentObject {
// expected-error@+1 {{Expected second argument of JS_OBJECT macro invocation to be ParentObject}}
JS_OBJECT(TestClass, JS::Object);
};

// Basename must exactly match the argument
namespace JS {

class TestClass : ::ParentObject {
// expected-error@+1 {{Expected second argument of JS_OBJECT macro invocation to be ::ParentObject}}
JS_OBJECT(TestClass, ParentObject);
};

}

// Nested classes
class Parent1 { };
class Parent2 : JS::Cell {
JS_CELL(Parent2, JS::Cell);
};
class Parent3 { };
class Parent4 : public Parent2 {
JS_CELL(Parent4, Parent2);
};

class NestedCellClass
: Parent1
, Parent3
, Parent4 {
// expected-error@+1 {{Expected second argument of JS_CELL macro invocation to be Parent4}}
JS_CELL(NestedCellClass, Parent2);
};
41 changes: 41 additions & 0 deletions Tests/ClangPlugins/LibJSGCTests/Macros/wrong_classname_arg.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* Copyright (c) 2024, Matthew Olsson <mattco@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/

// RUN: %clang++ -cc1 -verify %plugin_opts% %s 2>&1

#include <LibJS/Runtime/PrototypeObject.h>
#include <LibWeb/Bindings/PlatformObject.h>

// An incorrect first argument for JS_PROTOTYPE_OBJECT is a compile error, so that is not tested

class TestCellClass : JS::Cell {
// expected-error@+1 {{Expected first argument of JS_CELL macro invocation to be TestCellClass}}
JS_CELL(bad, JS::Cell);
};

class TestObjectClass : JS::Object {
// expected-error@+1 {{Expected first argument of JS_OBJECT macro invocation to be TestObjectClass}}
JS_OBJECT(bad, JS::Object);
};

class TestEnvironmentClass : JS::Environment {
// expected-error@+1 {{Expected first argument of JS_ENVIRONMENT macro invocation to be TestEnvironmentClass}}
JS_ENVIRONMENT(bad, JS::Environment);
};

class TestPlatformClass : Web::Bindings::PlatformObject {
// expected-error@+1 {{Expected first argument of WEB_PLATFORM_OBJECT macro invocation to be TestPlatformClass}}
WEB_PLATFORM_OBJECT(bad, Web::Bindings::PlatformObject);
};

struct Outer {
struct Inner;
};

struct Outer::Inner : JS::Cell {
// expected-error@+1 {{Expected first argument of JS_CELL macro invocation to be Outer::Inner}}
JS_CELL(Inner, JS::Cell);
};

0 comments on commit f860763

Please sign in to comment.