All files / src/codegen/generators generalFuncGen.ts

95.31% Statements 61/64
75.75% Branches 25/33
100% Functions 13/13
94.33% Lines 50/53

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117  1x 1x   1x   17x 17x         17x     17x         17x 17x         17x   17x               17x         17x                           17x 17x 17x 17x 1x   17x 4x   17x 3x     2x     17x 1x     1x     17x 2x     2x     17x 4x 4x   4x   17x 1x   17x 1x   17x   11x   6x 6x 5x   6x 6x 6x 6x 1x   10x   6x 6x    
import { ContractSchema } from "../contractSchema";
import { Generator, ind } from "../generator";
import { Feature } from "../../types";
 
export class GeneralFuncGen implements Generator {
    gen(schema: ContractSchema): string {
        const schemaURI = schema.schemaURI ? schema.schemaURI : "";
        const schemaURIFunction = `` +
        `function schemaURI() pure external override returns (string memory) {\n` +
        `    return "${schemaURI}";\n` +
        `}\n`;
    
        const imageURI = schema.imageURI && schema.imageURI.includes('{tokenID}') 
          ? `string.concat("${schema.imageURI.split('{tokenID}').join('", Strings.toString(tokenId), "')}")`
          : `"${schema.imageURI}"` || `""`;
        const imageURIFunction = `` +
        `function imageURI(uint256 tokenId) pure external override returns (string memory) {\n` +
        `    return ${imageURI};\n` +
        `}\n`;
    
        const baseURI = schema.baseURI ? schema.baseURI : "";
        const baseURIFunction = `` +
        `function _baseURI() internal pure virtual override returns (string memory) {\n` +
        `    return "${baseURI}";\n` +
        `}\n`;
 
        const interfaceFunction = this.getSupportsInterfaceFunc(schema);
    
        const storeMetadataFunction = `` +
        `function storeMetadata(uint256 tokenId, ${schema.getMetadataStructName()} memory data) public {\n` +
        `    if (!_checkTokenWriteAuth(tokenId)) {\n` +
        `        revert IPatchworkProtocol.NotAuthorized(msg.sender);\n` +
        `    }\n` +
        `    _metadataStorage[tokenId] = packMetadata(data);\n` +
        `}\n`;
    
        const loadMetadataFunction = `` +
        `function loadMetadata(uint256 tokenId) public view returns (${schema.getMetadataStructName()} memory data) {\n` +
        `    return unpackMetadata(_metadataStorage[tokenId]);\n` +
        `}\n`;
       
        return ind(4, `` +
        `${schemaURIFunction}\n` +
        `${imageURIFunction}\n` +
        `${baseURIFunction}\n` +
        `${interfaceFunction}` +
        `${storeMetadataFunction}\n` +
        `${loadMetadataFunction}\n`);
    }
 
    getSupportsInterfaceFunc(schema: ContractSchema): string {
        // bases = Patchwork721, PatchworkFragmentSingle, PatchworkFragmentMulti
        //   PatchworkPatch, PatchworkReversiblePatch, ... PatchworkLiteRef
        // support adds = mintable
        // TODO add interface
        let support = [];
        let bases = [];
        let features = schema.features;
        if (features.some((feature: Feature) => feature === Feature.FRAGMENTMULTI)) {
            bases.push(`PatchworkFragmentMulti`);
        }
        if (features.some((feature: Feature) => feature === Feature.FRAGMENTSINGLE)) {
            bases.push(`PatchworkFragmentSingle`);
        }
        if (features.some((feature: Feature) => feature === Feature.PATCH)) {
            Iif (features.some((feature: Feature) => feature === Feature.REVERSIBLE)) {
                bases.push(`PatchworkReversiblePatch`);
            } else {
                bases.push(`PatchworkPatch`);
            }
        }
        if (features.some((feature: Feature) => feature === Feature['1155PATCH'])) {
            Iif (features.some((feature: Feature) => feature === Feature.REVERSIBLE)) {
                bases.push(`PatchworkReversible1155Patch`);
            } else {
                bases.push(`Patchwork1155Patch`);
            }
        }
        if (features.some((feature: Feature) => feature === Feature.ACCOUNTPATCH)) {
            Iif (features.some((feature: Feature) => feature === Feature.REVERSIBLE)) {
                bases.push(`PatchworkReversibleAccountPatch`);
            } else {
                bases.push(`PatchworkAccountPatch`);
            }
        }
        if (schema.hasLiteRef()) {
            if (bases.length === 0) {
                bases.push(`Patchwork721`);
            }
            bases.push(`PatchworkLiteRef`);
        }
        if (features.some((feature: Feature) => feature === Feature.MINTABLE)) {
            support.push(`IPatchworkMintable`);
        }
        if (bases.length === 0 && support.length > 0) {
            bases.push(`Patchwork721`);
        }
        if (bases.length <= 1 && support.length === 0) {
            // No need for an override
            return ``;
        }
        let baseString = `override `;
        if (bases.length > 1) {
            baseString = `override(${bases.join(", ")}) `;
        }
        let func = `function supportsInterface(bytes4 interfaceID) public view virtual ${baseString}returns (bool) {\n`
        func += `    return `;
        support.map((value: string) => { func += `type(${value}).interfaceId == interfaceID ||\n        `; })
        if (bases.length === 1) {
            func += `super.supportsInterface(interfaceID)`
        } else {
            func += bases.map(value => `${value}.supportsInterface(interfaceID)`).join(' ||\n        ');
        }
        func += `;\n}\n\n`;
        return func;
    }
}