src/plugins/assert-nullability.ts (220 lines of code) (raw):
/**
* Copyright (c) 2016-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import * as AlgebraicType from '../algebraic-type';
import * as AlgebraicTypeUtils from '../algebraic-type-utils';
import * as Code from '../code';
import * as Error from '../error';
import * as FileWriter from '../file-writer';
import * as CLangCommon from '../clang-common';
import * as ObjC from '../objc';
import * as ObjCNullabilityUtils from '../objc-nullability-utils';
import * as ObjectSpec from '../object-spec';
import * as ObjectSpecCodeUtils from '../object-spec-code-utils';
function parameterAssertMacro(): ObjC.Macro {
return {
comments: [],
name: 'RMParameterAssert',
parameters: ['condition'],
code: 'NSCParameterAssert((condition))',
};
}
function canAssertExistenceForTypeOfObjectSpecAttribute(
attribute: ObjectSpec.Attribute,
) {
return ObjCNullabilityUtils.canAssertExistenceForType(
ObjectSpecCodeUtils.computeTypeOfAttribute(attribute),
);
}
function canAssertExistenceForTypeOfAlgebraicTypeSubtypeAttribute(
attribute: AlgebraicType.SubtypeAttribute,
) {
return ObjCNullabilityUtils.canAssertExistenceForType(
AlgebraicTypeUtils.computeTypeOfAttribute(attribute),
);
}
function parameterAssertMacroArray(
assumeNonnull: boolean,
attributeNullabilities: CLangCommon.Nullability[],
): ObjC.Macro[] {
if (
ObjCNullabilityUtils.nullabilityRequiresNonnullProtection(
assumeNonnull,
attributeNullabilities,
)
) {
return [parameterAssertMacro()];
} else {
return [];
}
}
export function createPlugin(): ObjectSpec.Plugin {
return {
additionalFiles: function (objectType: ObjectSpec.Type): Code.File[] {
return [];
},
transformBaseFile: function (
objectType: ObjectSpec.Type,
baseFile: Code.File,
): Code.File {
return baseFile;
},
additionalTypes: function (objectType: ObjectSpec.Type): ObjectSpec.Type[] {
return [];
},
attributes: function (objectType: ObjectSpec.Type): ObjectSpec.Attribute[] {
return [];
},
classMethods: function (objectType: ObjectSpec.Type): ObjC.Method[] {
return [];
},
transformFileRequest: function (
request: FileWriter.Request,
): FileWriter.Request {
return request;
},
fileType: function (objectType: ObjectSpec.Type): Code.FileType | null {
return null;
},
forwardDeclarations: function (
objectType: ObjectSpec.Type,
): ObjC.ForwardDeclaration[] {
return [];
},
functions: function (objectType: ObjectSpec.Type): ObjC.Function[] {
return [];
},
headerComments: function (objectType: ObjectSpec.Type): ObjC.Comment[] {
return [];
},
implementedProtocols: function (
objectType: ObjectSpec.Type,
): ObjC.ImplementedProtocol[] {
return [];
},
imports: function (objectType: ObjectSpec.Type): ObjC.Import[] {
return [];
},
instanceMethods: function (objectType: ObjectSpec.Type): ObjC.Method[] {
return [];
},
macros: function (objectType: ObjectSpec.Type): ObjC.Macro[] {
const assumeNonnull: boolean =
objectType.includes.indexOf('RMAssumeNonnull') >= 0;
const attributeNullabilities = objectType.attributes
.filter(canAssertExistenceForTypeOfObjectSpecAttribute)
.map((attribute) => attribute.nullability);
return parameterAssertMacroArray(assumeNonnull, attributeNullabilities);
},
properties: function (objectType: ObjectSpec.Type): ObjC.Property[] {
return [];
},
requiredIncludesToRun: ['RMAssertNullability'],
staticConstants: function (objectType: ObjectSpec.Type): ObjC.Constant[] {
return [];
},
validationErrors: function (objectType: ObjectSpec.Type): Error.Error[] {
return [];
},
nullability: function (
objectType: ObjectSpec.Type,
): ObjC.ClassNullability | null {
return null;
},
subclassingRestricted: function (objectType: ObjectSpec.Type): boolean {
return false;
},
};
}
export function createAlgebraicTypePlugin(): AlgebraicType.Plugin {
return {
additionalFiles: function (algebraicType: AlgebraicType.Type): Code.File[] {
return [];
},
transformBaseFile: function (
algebraicType: AlgebraicType.Type,
baseFile: Code.File,
): Code.File {
return baseFile;
},
blockTypes: function (algebraicType: AlgebraicType.Type): ObjC.BlockType[] {
return [];
},
classMethods: function (algebraicType: AlgebraicType.Type): ObjC.Method[] {
return [];
},
enumerations: function (
algebraicType: AlgebraicType.Type,
): ObjC.Enumeration[] {
return [];
},
transformFileRequest: function (
request: FileWriter.Request,
): FileWriter.Request {
return request;
},
fileType: function (
algebraicType: AlgebraicType.Type,
): Code.FileType | null {
return null;
},
forwardDeclarations: function (
algebraicType: AlgebraicType.Type,
): ObjC.ForwardDeclaration[] {
return [];
},
functions: function (algebraicType: AlgebraicType.Type): ObjC.Function[] {
return [];
},
headerComments: function (
algebraicType: AlgebraicType.Type,
): ObjC.Comment[] {
return [];
},
implementedProtocols: function (
algebraicType: AlgebraicType.Type,
): ObjC.ImplementedProtocol[] {
return [];
},
imports: function (algebraicType: AlgebraicType.Type): ObjC.Import[] {
return [];
},
instanceMethods: function (
algebraicType: AlgebraicType.Type,
): ObjC.Method[] {
return [];
},
instanceVariables: function (
algebraicType: AlgebraicType.Type,
): ObjC.InstanceVariable[] {
return [];
},
macros: function (algebraicType: AlgebraicType.Type): ObjC.Macro[] {
const assumeNonnull: boolean =
algebraicType.includes.indexOf('RMAssumeNonnull') >= 0;
const attributeNullabilities =
AlgebraicTypeUtils.allAttributesFromSubtypes(algebraicType.subtypes)
.filter(canAssertExistenceForTypeOfAlgebraicTypeSubtypeAttribute)
.map((attribute) => attribute.nullability);
return parameterAssertMacroArray(assumeNonnull, attributeNullabilities);
},
requiredIncludesToRun: ['RMAssertNullability'],
staticConstants: function (
algebraicType: AlgebraicType.Type,
): ObjC.Constant[] {
return [];
},
validationErrors: function (
algebraicType: AlgebraicType.Type,
): Error.Error[] {
return [];
},
nullability: function (
algebraicType: AlgebraicType.Type,
): ObjC.ClassNullability | null {
return null;
},
subclassingRestricted: function (
algebraicType: AlgebraicType.Type,
): boolean {
return false;
},
};
}