Tests: Add tests for ClangPlugin's macro validation

This commit is contained in:
Matthew Olsson 2024-04-11 08:20:29 -07:00 committed by Andrew Kaster
parent 36d032b208
commit f860763c77
Notes: sideshowbarker 2024-07-17 00:27:16 +09:00
6 changed files with 260 additions and 0 deletions

View File

@ -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 {
};

View File

@ -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
};

View File

@ -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);
};
}

View File

@ -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 {
};
};

View File

@ -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);
};

View File

@ -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);
};