New Mojom Parser: Validate the use of '&' and '?'
The parser was not validating that after a user-defined type reference is resolved, that if the reference used a '&' or a '?' (or both) that the reference had resolved to a type for which this makes sense. This patch implements that.
BUG=#461
R=azani@chromium.org
Review URL: https://codereview.chromium.org/1515343002 .
diff --git a/mojom/mojom_parser/mojom/types.go b/mojom/mojom_parser/mojom/types.go
index 83cc4f7..f723b08 100644
--- a/mojom/mojom_parser/mojom/types.go
+++ b/mojom/mojom_parser/mojom/types.go
@@ -813,6 +813,21 @@
if ref.scope != nil && ref.scope.file != nil {
file = ref.scope.file
}
+
+ if ref.IsInterfaceRequest() && ref.resolvedType.Kind() != UserDefinedTypeKindInterface {
+ message := fmt.Sprintf("Invalid interface request specification: %s. %s is not an interface type.",
+ ref.TypeName(), ref.ResolvedType().FullyQualifiedName())
+ message = UserErrorMessage(file, ref.token, message)
+ return fmt.Errorf(message)
+ }
+
+ if ref.Nullable() && ref.resolvedType.Kind() == UserDefinedTypeKindEnum {
+ message := fmt.Sprintf("The type %s is invalid because %s is an enum type and these may not be made nullable.",
+ ref.TypeName(), ref.ResolvedType().FullyQualifiedName())
+ message = UserErrorMessage(file, ref.token, message)
+ return fmt.Errorf(message)
+ }
+
if ref.resolvedType.Kind() != UserDefinedTypeKindEnum {
// A type ref has resolved to a non-enum type. Make sure it is not
// being used as either a map key or a constant declaration. Also
diff --git a/mojom/mojom_parser/parser/resolution_test.go b/mojom/mojom_parser/parser/resolution_test.go
index 9e3857f..80f4d7b 100644
--- a/mojom/mojom_parser/parser/resolution_test.go
+++ b/mojom/mojom_parser/parser/resolution_test.go
@@ -827,6 +827,66 @@
}
////////////////////////////////////////////////////////////
+ // Group 3: Invalid use of interface request.
+ ////////////////////////////////////////////////////////////
+
+ ////////////////////////////////////////////////////////////
+ // Test Case: Make an interface request out of a struct
+ ////////////////////////////////////////////////////////////
+ {
+ contents := `
+ struct Foo{
+ };
+
+ struct Bar{
+ Foo& x;
+ };
+ `
+ test.addTestCase(contents, []string{
+ "Invalid interface request specification",
+ "Foo&. Foo is not an interface type"})
+ }
+
+ ////////////////////////////////////////////////////////////
+ // Test Case: Make a nullable interface request out of a struct
+ ////////////////////////////////////////////////////////////
+ {
+ contents := `
+ struct Foo{
+ };
+
+ struct Bar{
+ Foo&? x;
+ };
+ `
+ test.addTestCase(contents, []string{
+ "Invalid interface request specification",
+ "Foo&?. Foo is not an interface type"})
+ }
+
+ ////////////////////////////////////////////////////////////
+ // Group 4: Invalid use of nullable
+ ////////////////////////////////////////////////////////////
+
+ ////////////////////////////////////////////////////////////
+ // Test Case: Make nullable enum.
+ ////////////////////////////////////////////////////////////
+ {
+ contents := `
+ enum Hats {
+ COWBOY,
+ TOP
+ };
+
+ struct Bar{
+ Hats? my_hat;
+ };
+ `
+ test.addTestCase(contents, []string{
+ "The type Hats? is invalid because Hats is an enum type and these may not be made nullable."})
+ }
+
+ ////////////////////////////////////////////////////////////
// Execute all of the test cases.
////////////////////////////////////////////////////////////
for i, c := range test.cases {