Reland "Improve support for arrays in Metal."

This reverts commit 38df4c8470ab3db7455005ab0c3599a95c791d2b.

Reason for revert: updated ArrayTypes test for ES2 compatibility

Original change's description:
> Revert "Improve support for arrays in Metal."
>
> This reverts commit dd904af5666b4746d4b9af5c1f03b47ac3ec73b2.
>
> Reason for revert: breaks ANGLE
>
> Original change's description:
> > Improve support for arrays in Metal.
> >
> > Arrays in Metal now use the `array<T, N>` type instead of the C-style
> > `T[N]` type. This gives them semantics much more in line with GLSL,
> > so they can be initialized and assigned like GLSL arrays.
> >
> > This allows the ArrayTypes and Assignment tests to pass, so they have
> > been added to our dm SkSL tests. (ArrayConstructors also passes, but
> > is not ES2-compliant so it is not enabled.)
> >
> > Change-Id: Id1028311963084befd0e044e11e223af6a064dda
> > Bug: skia:10761, skia:10760, skia:11022, skia:10939
> > Reviewed-on: https://skia-review.googlesource.com/c/skia/+/365699
> > Commit-Queue: John Stiles <johnstiles@google.com>
> > Auto-Submit: John Stiles <johnstiles@google.com>
> > Reviewed-by: Brian Osman <brianosman@google.com>
>
> TBR=brianosman@google.com,ethannicholas@google.com,johnstiles@google.com
>
> Change-Id: If6a18dea7d6a45fa7836e9129bf81c2e536f07e3
> No-Presubmit: true
> No-Tree-Checks: true
> No-Try: true
> Bug: skia:10761
> Bug: skia:10760
> Bug: skia:11022
> Bug: skia:10939
> Reviewed-on: https://skia-review.googlesource.com/c/skia/+/365976
> Reviewed-by: John Stiles <johnstiles@google.com>
> Commit-Queue: John Stiles <johnstiles@google.com>

TBR=brianosman@google.com,ethannicholas@google.com,johnstiles@google.com

Bug: skia:10761
Bug: skia:10760
Bug: skia:11022
Bug: skia:10939
Change-Id: Ia1c4917f5d3c41162d282b3093814d861707ad30
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/366144
Reviewed-by: John Stiles <johnstiles@google.com>
Commit-Queue: John Stiles <johnstiles@google.com>
diff --git a/src/sksl/SkSLMetalCodeGenerator.cpp b/src/sksl/SkSLMetalCodeGenerator.cpp
index 908f9df..37d8d20 100644
--- a/src/sksl/SkSLMetalCodeGenerator.cpp
+++ b/src/sksl/SkSLMetalCodeGenerator.cpp
@@ -109,15 +109,24 @@
 
 String MetalCodeGenerator::typeName(const Type& type) {
     switch (type.typeKind()) {
+        case Type::TypeKind::kArray:
+            SkASSERTF(type.columns() > 0, "invalid array size: %s", type.description().c_str());
+            return String::printf("array<%s, %d>",
+                                  this->typeName(type.componentType()).c_str(), type.columns());
+
         case Type::TypeKind::kVector:
             return this->typeName(type.componentType()) + to_string(type.columns());
+
         case Type::TypeKind::kMatrix:
             return this->typeName(type.componentType()) + to_string(type.columns()) + "x" +
                                   to_string(type.rows());
+
         case Type::TypeKind::kSampler:
             return "texture2d<float>"; // FIXME - support other texture types
+
         case Type::TypeKind::kEnum:
             return "int";
+
         default:
             if (type == *fContext.fTypes.fHalf) {
                 // FIXME - Currently only supporting floats in MSL to avoid type coercion issues.
@@ -141,36 +150,8 @@
     this->writeLine("};");
 }
 
-// Flags an error if an array type is found. Meant to be used in places where an array type might
-// appear in the SkSL/IR, but can't be represented by Metal.
-void MetalCodeGenerator::disallowArrayTypes(const Type& type, int offset) {
-    if (type.isArray()) {
-        fErrors.error(offset, "Metal does not support array types in this context");
-    }
-}
-
-// Writes the base type, stripping array suffixes. e.g. `float[2]` will output `float`.
-// Call `writeArrayDimensions` to write the type's accompanying array sizes.
-void MetalCodeGenerator::writeBaseType(const Type& type) {
-    switch (type.typeKind()) {
-        case Type::TypeKind::kArray:
-            this->writeBaseType(type.componentType());
-            break;
-        default:
-            this->write(this->typeName(type));
-            break;
-    }
-}
-
-// Writes the array suffix of a type, if one exists. e.g. `float[2][4]` will output `[2][4]`.
-void MetalCodeGenerator::writeArrayDimensions(const Type& type) {
-    if (type.isArray()) {
-        this->write("[");
-        if (type.columns() != Type::kUnsizedArray) {
-            this->write(to_string(type.columns()));
-        }
-        this->write("]");
-    }
+void MetalCodeGenerator::writeType(const Type& type) {
+    this->write(this->typeName(type));
 }
 
 void MetalCodeGenerator::writeExpression(const Expression& expr, Precedence parentPrecedence) {
@@ -242,7 +223,7 @@
     // `outVars` is non-null; in those places, we take the type of the VariableReference.
     //
     // float _skOutParamHelper0_originalFuncName(float _var0, float _var1, float& outParam) {
-    this->writeBaseType(call.type());
+    this->writeType(call.type());
     this->write(" ");
     this->write(name);
     this->write("(");
@@ -259,7 +240,7 @@
         this->writeModifiers(param->modifiers(), /*globalContext=*/false);
 
         const Type* type = outVars[index] ? &outVars[index]->type() : &arguments[index]->type();
-        this->writeBaseType(*type);
+        this->writeType(*type);
 
         if (param->modifiers().fFlags & Modifiers::kOut_Flag) {
             this->write("&");
@@ -273,7 +254,6 @@
             this->write(" _var");
             this->write(to_string(index));
         }
-        this->writeArrayDimensions(*type);
     }
     this->writeLine(") {");
 
@@ -283,7 +263,7 @@
             continue;
         }
         // float3 _var2[ = outParam.zyx];
-        this->writeBaseType(arguments[index]->type());
+        this->writeType(arguments[index]->type());
         this->write(" _var");
         this->write(to_string(index));
 
@@ -301,7 +281,7 @@
     // [int _skResult = ] myFunction(inputs, outputs, _globals, _var0, _var1, _var2, _var3);
     bool hasResult = (call.type().name() != "void");
     if (hasResult) {
-        this->writeBaseType(call.type());
+        this->writeType(call.type());
         this->write(" _skResult = ");
     }
 
@@ -1082,9 +1062,8 @@
     }
 
     // Explicitly invoke the constructor, passing in the necessary arguments.
-    this->writeBaseType(constructorType);
-    this->disallowArrayTypes(constructorType, c.fOffset);
-    this->write("(");
+    this->writeType(constructorType);
+    this->write(constructorType.isArray() ? "{" : "(");
     const char* separator = "";
     int scalarCount = 0;
     for (const std::unique_ptr<Expression>& arg : c.arguments()) {
@@ -1095,7 +1074,7 @@
             argType.columns() < constructorType.rows()) {
             // Merge scalars and smaller vectors together.
             if (!scalarCount) {
-                this->writeBaseType(constructorType.componentType());
+                this->writeType(constructorType.componentType());
                 this->write(to_string(constructorType.rows()));
                 this->write("(");
             }
@@ -1107,7 +1086,7 @@
             scalarCount = 0;
         }
     }
-    this->write(")");
+    this->write(constructorType.isArray() ? "}" : ")");
 }
 
 void MetalCodeGenerator::writeFragCoord() {
@@ -1500,7 +1479,7 @@
                     continue;
                 }
                 this->write(", constant ");
-                this->writeBaseType(intf.variable().type());
+                this->writeType(intf.variable().type());
                 this->write("& " );
                 this->write(fInterfaceBlockNameMap[&intf]);
                 this->write(" [[buffer(");
@@ -1520,8 +1499,7 @@
         }
         separator = ", ";
     } else {
-        this->writeBaseType(f.returnType());
-        this->disallowArrayTypes(f.returnType(), f.fOffset);
+        this->writeType(f.returnType());
         this->write(" ");
         this->writeName(f.name());
         this->write("(");
@@ -1532,13 +1510,12 @@
         separator = ", ";
         this->writeModifiers(param->modifiers(), /*globalContext=*/false);
         const Type* type = &param->type();
-        this->writeBaseType(*type);
+        this->writeType(*type);
         if (param->modifiers().fFlags & Modifiers::kOut_Flag) {
             this->write("&");
         }
         this->write(" ");
         this->writeName(param->name());
-        this->writeArrayDimensions(*type);
     }
     this->write(")");
     return true;
@@ -1698,10 +1675,9 @@
         }
         currentOffset += fieldSize;
         this->writeModifiers(field.fModifiers, /*globalContext=*/false);
-        this->writeBaseType(*fieldType);
+        this->writeType(*fieldType);
         this->write(" ");
         this->writeName(field.fName);
-        this->writeArrayDimensions(*fieldType);
         this->writeLine(";");
         if (parentIntf) {
             fInterfaceBlockMap[&field] = parentIntf;
@@ -1720,25 +1696,17 @@
     this->write(name);
 }
 
-void MetalCodeGenerator::writeVarDeclaration(const VarDeclaration& var, bool global) {
-    if (global && !(var.var().modifiers().fFlags & Modifiers::kConst_Flag)) {
+void MetalCodeGenerator::writeVarDeclaration(const VarDeclaration& varDecl, bool global) {
+    if (global && !(varDecl.var().modifiers().fFlags & Modifiers::kConst_Flag)) {
         return;
     }
-    this->writeModifiers(var.var().modifiers(), global);
-    this->writeBaseType(var.baseType());
-    this->disallowArrayTypes(var.baseType(), var.fOffset);
+    this->writeModifiers(varDecl.var().modifiers(), global);
+    this->writeType(varDecl.var().type());
     this->write(" ");
-    this->writeName(var.var().name());
-    if (var.arraySize() > 0) {
-        this->write("[");
-        this->write(to_string(var.arraySize()));
-        this->write("]");
-    } else if (var.arraySize() == Type::kUnsizedArray){
-        this->write("[]");
-    }
-    if (var.value()) {
+    this->writeName(varDecl.var().name());
+    if (varDecl.value()) {
         this->write(" = ");
-        this->writeVarInitializer(var.var(), *var.value());
+        this->writeVarInitializer(varDecl.var(), *varDecl.value());
     }
     this->write(";");
 }
@@ -1940,10 +1908,9 @@
                                                  "the same 'layout(set=...)'");
                 }
                 this->write("    ");
-                this->writeBaseType(var.type());
+                this->writeType(var.type());
                 this->write(" ");
                 this->writeName(var.name());
-                this->writeArrayDimensions(var.type());
                 this->write(";\n");
             }
         }
@@ -1962,10 +1929,9 @@
             if (var.modifiers().fFlags & Modifiers::kIn_Flag &&
                 -1 == var.modifiers().fLayout.fBuiltin) {
                 this->write("    ");
-                this->writeBaseType(var.type());
+                this->writeType(var.type());
                 this->write(" ");
                 this->writeName(var.name());
-                this->writeArrayDimensions(var.type());
                 if (-1 != var.modifiers().fLayout.fLocation) {
                     if (fProgram.fKind == Program::kVertex_Kind) {
                         this->write("  [[attribute(" +
@@ -1996,10 +1962,9 @@
             if (var.modifiers().fFlags & Modifiers::kOut_Flag &&
                 -1 == var.modifiers().fLayout.fBuiltin) {
                 this->write("    ");
-                this->writeBaseType(var.type());
+                this->writeType(var.type());
                 this->write(" ");
                 this->writeName(var.name());
-                this->writeArrayDimensions(var.type());
 
                 int location = var.modifiers().fLayout.fLocation;
                 if (location < 0) {
@@ -2088,10 +2053,9 @@
         void visitTexture(const Type& type, const String& name) override {
             this->addElement();
             fCodeGen->write("    ");
-            fCodeGen->writeBaseType(type);
+            fCodeGen->writeType(type);
             fCodeGen->write(" ");
             fCodeGen->writeName(name);
-            fCodeGen->writeArrayDimensions(type);
             fCodeGen->write(";\n");
         }
         void visitSampler(const Type&, const String& name) override {
@@ -2103,10 +2067,9 @@
         void visitVariable(const Variable& var, const Expression* value) override {
             this->addElement();
             fCodeGen->write("    ");
-            fCodeGen->writeBaseType(var.type());
+            fCodeGen->writeType(var.type());
             fCodeGen->write(" ");
             fCodeGen->writeName(var.name());
-            fCodeGen->writeArrayDimensions(var.type());
             fCodeGen->write(";\n");
         }
         void addElement() {