diff --git a/docs/examples/output-selection.rst b/docs/examples/output-selection.rst new file mode 100644 index 000000000000..3e7021b4c825 --- /dev/null +++ b/docs/examples/output-selection.rst @@ -0,0 +1,245 @@ +.. index:: ! output selection, compilation, compiler output + +******************* +Output Selection Examples +******************* + +.. _output-selection-examples: + +This document provides examples of using the ``outputSelection`` field in the Standard JSON interface to optimize your compilation workflow. + +Basic Output Selection +===================== + +Here's a simple example to get started with output selection: + +.. code-block:: javascript + + { + "language": "Solidity", + "sources": { + "contract.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.7.0 <0.9.0;\n\ncontract MyContract {\n uint256 private value;\n \n function setValue(uint256 _value) public {\n value = _value;\n }\n \n function getValue() public view returns (uint256) {\n return value;\n }\n}" + } + }, + "settings": { + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode.object" + ] + } + } + } + } + +This example requests only the ABI and the bytecode object for all contracts in all files. + +Development vs Production +======================== + +For development environments, you may want more detailed output, while production builds might need a minimal set of outputs. + +Development Environment: + +.. code-block:: javascript + + { + "settings": { + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "evm.gasEstimates", + "evm.assembly" + ], + "": [ + "ast" + ] + } + } + } + } + +Production Environment: + +.. code-block:: javascript + + { + "settings": { + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode.object", + "evm.deployedBytecode.object" + ] + } + } + } + } + +Targeted Contract Compilation +============================ + +When working with many contracts, you can target specific contracts to speed up compilation: + +.. code-block:: javascript + + { + "settings": { + "outputSelection": { + "MainContract.sol": { + "MainContract": [ + "abi", + "evm.bytecode.object", + "evm.deployedBytecode.object" + ] + }, + "*": { + "": [ + "ast" + ] + } + } + } + } + +This example generates outputs only for ``MainContract`` in ``MainContract.sol`` while still generating AST for all source files. + +Experimental Outputs +=================== + +To request experimental outputs along with standard ones: + +.. code-block:: javascript + + { + "settings": { + "outputSelection": { + "*": { + "*": [ + "*", // All standard outputs + "ir", // Explicitly request experimental IR output + "irOptimized" // Explicitly request optimized IR + ] + } + } + } + } + +Optimizing for Framework Usage +============================ + +For frameworks that need specific outputs for different operations: + +Contract Verification: + +.. code-block:: javascript + + { + "settings": { + "outputSelection": { + "*": { + "*": [ + "metadata" + ] + } + } + } + } + +Contract Interaction: + +.. code-block:: javascript + + { + "settings": { + "outputSelection": { + "*": { + "*": [ + "abi" + ] + } + } + } + } + +Contract Deployment: + +.. code-block:: javascript + + { + "settings": { + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode.object", + "evm.bytecode.linkReferences" + ] + } + } + } + } + +Complete Example with Multiple Files +================================== + +This example shows a more complex scenario with multiple files and specific output needs: + +.. code-block:: javascript + + { + "language": "Solidity", + "sources": { + "Token.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ncontract Token {\n // token implementation\n}" + }, + "Marketplace.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport './Token.sol';\n\ncontract Marketplace {\n // marketplace implementation using Token\n}" + }, + "Utils.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nlibrary Utils {\n // utility functions\n}" + } + }, + "settings": { + "outputSelection": { + "Marketplace.sol": { + "Marketplace": [ + "abi", + "evm.bytecode.object", + "evm.deployedBytecode.object", + "evm.gasEstimates" + ] + }, + "Token.sol": { + "Token": [ + "abi" + ] + }, + "Utils.sol": { + "Utils": [ + "abi", + "evm.bytecode.object" + ] + }, + "*": { + "": [ + "ast" + ] + } + } + } + } + +This selection would: +1. Generate full bytecode and gas estimates for the Marketplace contract +2. Generate only ABI for the Token contract (since it's imported but we might only need its interface) +3. Generate ABI and bytecode for the Utils library +4. Generate AST for all source files diff --git a/docs/solidity-by-example.rst b/docs/solidity-by-example.rst index 4b0f3e13f291..4086514e87bc 100644 --- a/docs/solidity-by-example.rst +++ b/docs/solidity-by-example.rst @@ -10,4 +10,9 @@ Solidity by Example .. include:: examples/micropayment.rst -.. include:: examples/modular.rst \ No newline at end of file +.. include:: examples/modular.rst + +.. toctree:: + :maxdepth: 1 + + examples/output-selection.rst diff --git a/docs/using-the-compiler.rst b/docs/using-the-compiler.rst index 23e83baec4e6..50a9543dbec1 100644 --- a/docs/using-the-compiler.rst +++ b/docs/using-the-compiler.rst @@ -695,3 +695,133 @@ Error Types 13. ``YulException``: Error during Yul code generation - this should be reported as an issue. 14. ``Warning``: A warning, which didn't stop the compilation, but should be addressed if possible. 15. ``Info``: Information that the compiler thinks the user might find useful, but is not dangerous and does not necessarily need to be addressed. + +.. _output-selection-documentation: + +Output Selection Deep Dive +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The ``outputSelection`` field allows fine-grained control over which compiler outputs to generate for each source file and contract. +Understanding its syntax and semantics can help optimize compilation time and reduce unnecessary outputs. + +For more detailed examples showing how to use ``outputSelection`` effectively in different scenarios, see the :doc:`examples/output-selection` page. + +Syntax and Structure +~~~~~~~~~~~~~~~~~~~ + +The ``outputSelection`` field uses a two-level nested JSON object with the following structure: + +.. code-block:: javascript + + "outputSelection": { + // First level: source file name (or wildcard) + "": { + // Second level: contract name (or wildcard or empty string) + "": [ + // List of requested outputs + "", "", ... + ] + } + } + +Special Values +~~~~~~~~~~~~~ + +* ``"*"`` (asterisk) as a file name: Matches all source files. +* ``"*"`` as a contract name: Matches all contracts in the specified file. +* ``""`` (empty string) as a contract name: Used for outputs that apply to the entire source file rather than specific contracts (e.g., ``ast``). +* ``"*"`` as an output: Requests all standard outputs, with some exceptions noted below. + +Wildcards and Matching Rules +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +1. The wildcard ``"*"`` is recognized as a special value only when it appears exactly as ``"*"``. Patterns like ``"*.sol"`` are interpreted literally and will not match any files unless a file is actually named ``"*.sol"``. + +2. When using ``"*"`` as an output selector, it does not match experimental outputs by default. As of Solidity 0.8.x, experimental outputs include: + + * ``"ir"`` + * ``"irAst"`` + * ``"irOptimized"`` + * ``"irOptimizedAst"`` + * ``"yulCFGJson"`` + * ``"ethdebug"`` (and any output containing ``"ethdebug"``) + + These must be requested explicitly or with the appropriate compiler settings. + +3. Overlapping selections are combined. For example, if you specify both ``"*": { "*": ["abi"] }`` and ``"MyFile.sol": { "MyContract": ["evm"] }``, then ``MyContract`` in ``MyFile.sol`` will have both ``abi`` and all ``evm`` outputs generated. + +Example Patterns +~~~~~~~~~~~~~~~ + +1. Request everything for all files and contracts: + + .. code-block:: javascript + + "outputSelection": { "*": { "*": [ "*" ], "": [ "*" ] } } + + Note: This does not include experimental outputs. + +2. Request ABI only for all contracts: + + .. code-block:: javascript + + "outputSelection": { "*": { "*": [ "abi" ] } } + +3. Request AST for all files plus bytecode for specific contracts: + + .. code-block:: javascript + + "outputSelection": { + "*": { "": [ "ast" ] }, + "Main.sol": { "MainContract": [ "evm.bytecode.object" ] } + } + +Performance Considerations +~~~~~~~~~~~~~~~~~~~~~~~~~ + +1. **Lazy Compilation**: The compiler performs only the compilation stages required by the requested outputs. For example: + + * If you request only ``"abi"``, the compiler will not generate bytecode + * If you request only ``"ir"``, the compiler will not proceed to EVM bytecode generation + +2. **Compilation Stages and Dependencies**: + + * **Parsing**: Required for all outputs + * **Analysis**: Required for most outputs including ABI + * **IR Generation**: Required for IR-related outputs and bytecode when using ``viaIR: true`` + * **IR Optimization**: Required for optimized IR outputs + * **Bytecode Generation**: Required for EVM-related outputs + +3. **Implicit Dependencies**: Some outputs trigger compilation of related contracts. For example: + + * Requesting bytecode for a contract will compile any libraries it uses + * Inheritance relationships may require compilation of parent contracts + +Best Practices +~~~~~~~~~~~~~ + +1. **Framework Optimization**: Frameworks should request only the outputs they actually need + + * Bad: ``{ "*": { "*": [ "*" ] } }`` (compiles everything) + * Good: ``{ "*": { "*": [ "abi", "evm.bytecode.object" ] } }`` (specific outputs only) + +2. **Development vs. Production**: Use different output selections for different environments + + * Development: Include debugging info like source maps + * Production: Include only essential outputs + +3. **Avoid Redundancy**: Don't request the same output through multiple patterns + + * Redundant: ``{ "*": { "*": [ "abi" ] }, "Contract.sol": { "MyContract": [ "abi" ] } }`` + * Better: ``{ "*": { "*": [ "abi" ] } }`` + +Version Compatibility +~~~~~~~~~~~~~~~~~~~~ + +The behavior of ``outputSelection`` has evolved across Solidity versions: + +* Pre-0.7.0: Limited wildcards support and different experimental output handling +* 0.7.0+: Enhanced wildcards support but still with limitations for experimental outputs +* 0.8.0+: Current behavior as documented above + +Legacy output selection via command-line options remains supported but using the JSON interface with specific output selection is recommended for production environments.