Add Type::isArray and Type::isStruct helper methods.

These methods improve readability for simple, commonly-performed type
checks.

We already had a (very rarely-used) helper function `isArrayed` which
was only applicable to texture and sampler types. To avoid potential
confusion, this has been renamed to `isArrayedTexture`.

Change-Id: Ibec9d872ff3b415964b842c96ddc1b5b271ac883
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/340720
Commit-Queue: John Stiles <johnstiles@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
Auto-Submit: John Stiles <johnstiles@google.com>
diff --git a/src/core/SkRuntimeEffect.cpp b/src/core/SkRuntimeEffect.cpp
index c8d180a..402a0e1 100644
--- a/src/core/SkRuntimeEffect.cpp
+++ b/src/core/SkRuntimeEffect.cpp
@@ -216,7 +216,7 @@
                 uni.fCount = 1;
 
                 const SkSL::Type* type = &var.type();
-                if (type->typeKind() == SkSL::Type::TypeKind::kArray) {
+                if (type->isArray()) {
                     uni.fFlags |= Uniform::kArray_Flag;
                     uni.fCount = type->columns();
                     type = &type->componentType();
diff --git a/src/sksl/SkSLCPPCodeGenerator.cpp b/src/sksl/SkSLCPPCodeGenerator.cpp
index 2c1963a..cdad72d 100644
--- a/src/sksl/SkSLCPPCodeGenerator.cpp
+++ b/src/sksl/SkSLCPPCodeGenerator.cpp
@@ -153,7 +153,7 @@
                                             const Layout& layout,
                                             const String& cppCode,
                                             std::vector<String>* formatArgs) {
-    if (type.typeKind() == Type::TypeKind::kArray) {
+    if (type.isArray()) {
         String result("[");
         const char* separator = "";
         for (int i = 0; i < type.columns(); i++) {
@@ -727,7 +727,7 @@
         this->writef("        if (%s) {\n    ", String(var.modifiers().fLayout.fWhen).c_str());
     }
     String name(var.name());
-    if (var.type().typeKind() != Type::TypeKind::kArray) {
+    if (!var.type().isArray()) {
         this->writef("        %sVar = args.fUniformHandler->addUniform(&_outer, "
                      "kFragment_GrShaderFlag, %s, \"%s\");\n",
                      HCodeGenerator::FieldName(name.c_str()).c_str(),
diff --git a/src/sksl/SkSLCPPUniformCTypes.cpp b/src/sksl/SkSLCPPUniformCTypes.cpp
index 6b27c83..0dc8dee 100644
--- a/src/sksl/SkSLCPPUniformCTypes.cpp
+++ b/src/sksl/SkSLCPPUniformCTypes.cpp
@@ -254,7 +254,7 @@
 // ctype and supports the sksl type of the variable.
 const UniformCTypeMapper* UniformCTypeMapper::Get(const Context& context, const Type& type,
                                                   const Layout& layout) {
-    if (type.typeKind() == Type::TypeKind::kArray) {
+    if (type.isArray()) {
         const UniformCTypeMapper* base = Get(context, type.componentType(), layout);
         return base ? base->arrayMapper(type.columns()) : nullptr;
     }
diff --git a/src/sksl/SkSLGLSLCodeGenerator.cpp b/src/sksl/SkSLGLSLCodeGenerator.cpp
index 9a340fc..42344c8 100644
--- a/src/sksl/SkSLGLSLCodeGenerator.cpp
+++ b/src/sksl/SkSLGLSLCodeGenerator.cpp
@@ -86,7 +86,7 @@
 String GLSLCodeGenerator::getTypeName(const Type& type) {
     String result = this->getBaseTypeName(type);
 
-    for (const Type* t = &type; t->typeKind() == Type::TypeKind::kArray; t = &t->componentType()) {
+    for (const Type* t = &type; t->isArray(); t = &t->componentType()) {
         if (t->columns() == Type::kUnsizedArray) {
             result += "[]";
         } else {
@@ -195,7 +195,7 @@
 }
 
 void GLSLCodeGenerator::writeType(const Type& type) {
-    if (type.typeKind() == Type::TypeKind::kStruct) {
+    if (type.isStruct()) {
         if (!this->writeStructDefinition(type)) {
             this->write(type.name());
         }
@@ -1059,7 +1059,7 @@
         this->writeModifiers(param->modifiers(), false);
         std::vector<int> sizes;
         const Type* type = &param->type();
-        while (type->typeKind() == Type::TypeKind::kArray) {
+        while (type->isArray()) {
             sizes.push_back(type->columns());
             type = &type->componentType();
         }
@@ -1204,7 +1204,7 @@
     this->writeLine(intf.typeName() + " {");
     fIndentation++;
     const Type* structType = &intf.variable().type();
-    while (structType->typeKind() == Type::TypeKind::kArray) {
+    while (structType->isArray()) {
         structType = &structType->componentType();
     }
     for (const auto& f : structType->fields()) {
diff --git a/src/sksl/SkSLHCodeGenerator.cpp b/src/sksl/SkSLHCodeGenerator.cpp
index 8f026c4..567f818 100644
--- a/src/sksl/SkSLHCodeGenerator.cpp
+++ b/src/sksl/SkSLHCodeGenerator.cpp
@@ -33,7 +33,7 @@
 
 String HCodeGenerator::ParameterType(const Context& context, const Type& type,
                                      const Layout& layout) {
-    if (type.typeKind() == Type::TypeKind::kArray) {
+    if (type.isArray()) {
         return String::printf("std::array<%s>", ParameterType(context, type.componentType(),
                                                               layout).c_str());
     }
@@ -46,7 +46,7 @@
 
 Layout::CType HCodeGenerator::ParameterCType(const Context& context, const Type& type,
                                      const Layout& layout) {
-    SkASSERT(type.typeKind() != Type::TypeKind::kArray);
+    SkASSERT(!type.isArray());
     if (layout.fCType != Layout::CType::kDefault) {
         return layout.fCType;
     }
diff --git a/src/sksl/SkSLIRGenerator.cpp b/src/sksl/SkSLIRGenerator.cpp
index cf9fc0f..a784d84 100644
--- a/src/sksl/SkSLIRGenerator.cpp
+++ b/src/sksl/SkSLIRGenerator.cpp
@@ -334,7 +334,7 @@
             return t.isVector() && t.componentType().isFloat() &&
                    (t.columns() == 3 || t.columns() == 4);
         };
-        if (!validColorXformType(*baseType) && !(baseType->typeKind() == Type::TypeKind::kArray &&
+        if (!validColorXformType(*baseType) && !(baseType->isArray() &&
                                                  validColorXformType(baseType->componentType()))) {
             fErrors.error(decls.fOffset,
                           "'srgb_unpremul' is only permitted on half3, half4, float3, or float4 "
@@ -879,9 +879,8 @@
                type_to_grsltype(fContext, *t, &unusedSLType);
 #endif
     };
-    if (returnType->nonnullable() == *fContext.fFragmentProcessor_Type ||
-        returnType->typeKind() == Type::TypeKind::kArray ||
-        !typeIsAllowed(returnType)) {
+    if (returnType->isArray() || !typeIsAllowed(returnType) ||
+        returnType->nonnullable() == *fContext.fFragmentProcessor_Type) {
         fErrors.error(f.fOffset,
                       "functions may not return type '" + returnType->displayName() + "'");
         return;
@@ -1081,7 +1080,7 @@
     if (!type) {
         return nullptr;
     }
-    if (type->typeKind() != Type::TypeKind::kStruct) {
+    if (!type->isStruct()) {
         fErrors.error(node.fOffset, "expected a struct here, found '" + type->name() + "'");
         return nullptr;
     }
@@ -1135,7 +1134,7 @@
                     fErrors.error(decl->fOffset,
                                 "initializers are not permitted on interface block fields");
                 }
-                if (vd.var().type().typeKind() == Type::TypeKind::kArray &&
+                if (vd.var().type().isArray() &&
                     vd.var().type().columns() == Type::kUnsizedArray) {
                     haveRuntimeArray = true;
                 }
@@ -1266,7 +1265,7 @@
     if (type.isPrivate()) {
         return true;
     }
-    if (type.typeKind() == Type::TypeKind::kStruct) {
+    if (type.isStruct()) {
         for (const auto& f : type.fields()) {
             if (this->typeContainsPrivateFields(*f.fType)) {
                 return true;
@@ -2353,10 +2352,9 @@
         // argument is already the right type, just return it
         return std::move(args[0]);
     }
-    Type::TypeKind kind = type.typeKind();
     if (type.isNumber()) {
         return this->convertNumberConstructor(offset, type, std::move(args));
-    } else if (kind == Type::TypeKind::kArray) {
+    } else if (type.isArray()) {
         const Type& base = type.componentType();
         for (size_t i = 0; i < args.size(); i++) {
             args[i] = this->coerce(std::move(args[i]), base);
@@ -2365,7 +2363,7 @@
             }
         }
         return std::make_unique<Constructor>(offset, &type, std::move(args));
-    } else if (kind == Type::TypeKind::kVector || kind == Type::TypeKind::kMatrix) {
+    } else if (type.isVector() || type.isMatrix()) {
         return this->convertCompoundConstructor(offset, type, std::move(args));
     } else {
         fErrors.error(offset, "cannot construct '" + type.displayName() + "'");
@@ -2469,9 +2467,7 @@
         }
     }
     const Type& baseType = base->type();
-    if (baseType.typeKind() != Type::TypeKind::kArray &&
-        !baseType.isMatrix() &&
-        !baseType.isVector()) {
+    if (!baseType.isArray() && !baseType.isMatrix() && !baseType.isVector()) {
         fErrors.error(base->fOffset, "expected array, but found '" + baseType.displayName() +
                                      "'");
         return nullptr;
diff --git a/src/sksl/SkSLInliner.cpp b/src/sksl/SkSLInliner.cpp
index 34e3b8b..f1e4052 100644
--- a/src/sksl/SkSLInliner.cpp
+++ b/src/sksl/SkSLInliner.cpp
@@ -195,7 +195,7 @@
 }
 
 static const Type* copy_if_needed(const Type* src, SymbolTable& symbolTable) {
-    if (src->typeKind() == Type::TypeKind::kArray) {
+    if (src->isArray()) {
         const Type* innerType = copy_if_needed(&src->componentType(), symbolTable);
         return symbolTable.takeOwnershipOfSymbol(std::make_unique<Type>(src->name(),
                                                                         src->typeKind(),
diff --git a/src/sksl/SkSLMetalCodeGenerator.cpp b/src/sksl/SkSLMetalCodeGenerator.cpp
index 07c8380..500e918 100644
--- a/src/sksl/SkSLMetalCodeGenerator.cpp
+++ b/src/sksl/SkSLMetalCodeGenerator.cpp
@@ -134,7 +134,7 @@
 // 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) {
-    if (type.typeKind() == Type::TypeKind::kArray) {
+    if (type.isArray()) {
         fErrors.error(type.fOffset, "Metal does not support array types in this context");
     }
 }
@@ -159,7 +159,7 @@
 
 // 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.typeKind() == Type::TypeKind::kArray) {
+    if (type.isArray()) {
         this->write("[");
         if (type.columns() != Type::kUnsizedArray) {
             this->write(to_string(type.columns()));
@@ -1246,7 +1246,7 @@
     this->write("struct ");
     this->writeLine(intf.typeName() + " {");
     const Type* structType = &intf.variable().type();
-    while (structType->typeKind() == Type::TypeKind::kArray) {
+    while (structType->isArray()) {
         structType = &structType->componentType();
     }
     fWrittenStructs.push_back(structType);
@@ -1664,7 +1664,7 @@
             // here, since globals are all embedded in a sub-struct.
             const Type* type = &e->as<GlobalVarDeclaration>().declaration()
                                  ->as<VarDeclaration>().baseType();
-            if (type->typeKind() == Type::TypeKind::kStruct) {
+            if (type->isStruct()) {
                 if (this->writeStructDefinition(*type)) {
                     this->writeLine(";");
                 }
diff --git a/src/sksl/SkSLParser.cpp b/src/sksl/SkSLParser.cpp
index db91a4a..5b5acfe 100644
--- a/src/sksl/SkSLParser.cpp
+++ b/src/sksl/SkSLParser.cpp
@@ -29,7 +29,7 @@
         return true;
     }
 
-    if (type.typeKind() == Type::TypeKind::kStruct) {
+    if (type.isStruct()) {
         for (const Type::Field& f : type.fields()) {
             if (struct_is_too_deeply_nested(*f.fType, limit - 1)) {
                 return true;
diff --git a/src/sksl/SkSLSPIRVCodeGenerator.cpp b/src/sksl/SkSLSPIRVCodeGenerator.cpp
index bcf45f8..b8fcc60 100644
--- a/src/sksl/SkSLSPIRVCodeGenerator.cpp
+++ b/src/sksl/SkSLSPIRVCodeGenerator.cpp
@@ -442,9 +442,7 @@
                                    SpvDecorationRelaxedPrecision, fDecorationBuffer);
         }
         offset += size;
-        Type::TypeKind kind = field.fType->typeKind();
-        if ((kind == Type::TypeKind::kArray || kind == Type::TypeKind::kStruct) &&
-            offset % alignment != 0) {
+        if ((field.fType->isArray() || field.fType->isStruct()) && offset % alignment != 0) {
             offset += alignment - offset % alignment;
         }
     }
@@ -483,7 +481,7 @@
 SpvId SPIRVCodeGenerator::getType(const Type& rawType, const MemoryLayout& layout) {
     const Type& type = this->getActualType(rawType);
     String key = type.name();
-    if (type.typeKind() == Type::TypeKind::kStruct || type.typeKind() == Type::TypeKind::kArray) {
+    if (type.isStruct() || type.isArray()) {
         key += to_string((int)layout.fStd);
     }
     auto entry = fTypeMap.find(key);
@@ -566,7 +564,7 @@
             case Type::TypeKind::kTexture: {
                 this->writeInstruction(SpvOpTypeImage, result,
                                        this->getType(*fContext.fFloat_Type, layout),
-                                       type.dimensions(), type.isDepth(), type.isArrayed(),
+                                       type.dimensions(), type.isDepth(), type.isArrayedTexture(),
                                        type.isMultisampled(), type.isSampled() ? 1 : 2,
                                        SpvImageFormatUnknown, fConstantBuffer);
                 fImageTypeMap[key] = result;
@@ -1534,7 +1532,7 @@
 
 SpvId SPIRVCodeGenerator::writeArrayConstructor(const Constructor& c, OutputStream& out) {
     const Type& type = c.type();
-    SkASSERT(type.typeKind() == Type::TypeKind::kArray);
+    SkASSERT(type.isArray());
     // go ahead and write the arguments so we don't try to write new instructions in the middle of
     // an instruction
     std::vector<SpvId> arguments;
diff --git a/src/sksl/ir/SkSLInterfaceBlock.h b/src/sksl/ir/SkSLInterfaceBlock.h
index 7e2c656..65c13bcc 100644
--- a/src/sksl/ir/SkSLInterfaceBlock.h
+++ b/src/sksl/ir/SkSLInterfaceBlock.h
@@ -72,7 +72,7 @@
     String description() const override {
         String result = this->variable().modifiers().description() + this->typeName() + " {\n";
         const Type* structType = &this->variable().type();
-        while (structType->typeKind() == Type::TypeKind::kArray) {
+        while (structType->isArray()) {
             structType = &structType->componentType();
         }
         for (const auto& f : structType->fields()) {
diff --git a/src/sksl/ir/SkSLSymbolTable.cpp b/src/sksl/ir/SkSLSymbolTable.cpp
index fb102fa..efb7f73 100644
--- a/src/sksl/ir/SkSLSymbolTable.cpp
+++ b/src/sksl/ir/SkSLSymbolTable.cpp
@@ -124,7 +124,7 @@
 const Type* SymbolTable::addArrayDimension(const Type* type, int arraySize) {
     if (arraySize != 0) {
         // SkSL doesn't support multi-dimensional arrays.
-        SkASSERT(type->typeKind() != Type::TypeKind::kArray);
+        SkASSERT(!type->isArray());
         String baseName = type->name();
         String arrayName = (arraySize != Type::kUnsizedArray)
                                    ? String::printf("%s[%d]", baseName.c_str(), arraySize)
diff --git a/src/sksl/ir/SkSLType.h b/src/sksl/ir/SkSLType.h
index 1425512..29f3c4c 100644
--- a/src/sksl/ir/SkSLType.h
+++ b/src/sksl/ir/SkSLType.h
@@ -189,7 +189,7 @@
     , fColumns(columns)
     , fRows(1)
     , fDimensions(SpvDim1D) {
-        SkASSERT(fColumns > 0 || (fTypeKind == TypeKind::kArray && fColumns == kUnsizedArray));
+        SkASSERT(this->columns() > 0 || (this->isArray() && this->columns() == kUnsizedArray));
         fName = StringFragment(fNameString.c_str(), fNameString.length());
     }
 
@@ -204,14 +204,14 @@
     , fDimensions(SpvDim1D) {}
 
     // Create a texture type.
-    Type(const char* name, SpvDim_ dimensions, bool isDepth, bool isArrayed, bool isMultisampled,
-         bool isSampled)
+    Type(const char* name, SpvDim_ dimensions, bool isDepth, bool isArrayedTexture,
+         bool isMultisampled, bool isSampled)
     : INHERITED(-1, kSymbolKind, name)
     , fTypeKind(TypeKind::kTexture)
     , fNumberKind(NumberKind::kNonnumeric)
     , fDimensions(dimensions)
     , fIsDepth(isDepth)
-    , fIsArrayed(isArrayed)
+    , fIsArrayed(isArrayedTexture)
     , fIsMultisampled(isMultisampled)
     , fIsSampled(isSampled) {}
 
@@ -222,7 +222,7 @@
     , fNumberKind(NumberKind::kNonnumeric)
     , fDimensions(textureType.dimensions())
     , fIsDepth(textureType.isDepth())
-    , fIsArrayed(textureType.isArrayed())
+    , fIsArrayed(textureType.isArrayedTexture())
     , fIsMultisampled(textureType.isMultisampled())
     , fIsSampled(textureType.isSampled())
     , fTextureType(&textureType) {}
@@ -376,8 +376,7 @@
      * For all other types, causes an SkASSERTion failure.
      */
     int columns() const {
-        SkASSERT(fTypeKind == TypeKind::kScalar || fTypeKind == TypeKind::kVector ||
-                 fTypeKind == TypeKind::kMatrix || fTypeKind == TypeKind::kArray);
+        SkASSERT(this->isScalar() || this->isVector() || this->isMatrix() || this->isArray());
         return fColumns;
     }
 
@@ -391,7 +390,7 @@
     }
 
     const std::vector<Field>& fields() const {
-        SkASSERT(fTypeKind == TypeKind::kStruct || fTypeKind == TypeKind::kOther);
+        SkASSERT(this->isStruct() || fTypeKind == TypeKind::kOther);
         return fFields;
     }
 
@@ -414,7 +413,7 @@
         return fIsDepth;
     }
 
-    bool isArrayed() const {
+    bool isArrayedTexture() const {
         SkASSERT(TypeKind::kSampler == fTypeKind || TypeKind::kTexture == fTypeKind);
         return fIsArrayed;
     }
@@ -431,6 +430,14 @@
         return fTypeKind == TypeKind::kMatrix;
     }
 
+    bool isArray() const {
+        return fTypeKind == TypeKind::kArray;
+    }
+
+    bool isStruct() const {
+        return fTypeKind == TypeKind::kStruct;
+    }
+
     bool isMultisampled() const {
         SkASSERT(TypeKind::kSampler == fTypeKind || TypeKind::kTexture == fTypeKind);
         return fIsMultisampled;
diff --git a/src/sksl/ir/SkSLVariableReference.cpp b/src/sksl/ir/SkSLVariableReference.cpp
index 8e7686a..12050f4 100644
--- a/src/sksl/ir/SkSLVariableReference.cpp
+++ b/src/sksl/ir/SkSLVariableReference.cpp
@@ -55,7 +55,7 @@
     const Expression* initialValue = this->variable()->initialValue();
     if ((this->variable()->modifiers().fFlags & Modifiers::kConst_Flag) && initialValue &&
         initialValue->isCompileTimeConstant() &&
-        this->type().typeKind() != Type::TypeKind::kArray) {
+        !this->type().isArray()) {
         return initialValue->clone();
     }
     std::unique_ptr<Expression>** exprPPtr = definitions.find(this->variable());