Cross File Support
Skittles supports sharing types, functions, and constants across multiple contract files. Before compilation, the compiler pre scans all files in the contracts directory to collect shared definitions, then makes them available to every contract.
Shared Types
Interfaces (structs) and enums defined in one file can be used in any other contract file:
import { address } from "skittles";
export enum VaultStatus {
Active,
Paused,
}
export interface StakeInfo {
amount: number;
timestamp: number;
account: address;
}
import { VaultStatus, StakeInfo } from "./types";
export class Staking {
public status: VaultStatus;
public getStakeInfo(account: address): StakeInfo {
let info: StakeInfo = {
amount: this.deposits[account],
timestamp: this.depositTimestamps[account],
account: account,
};
return info;
}
}
The import syntax is standard TypeScript. Skittles resolves the types across files during the pre scan phase. The generated Solidity includes the struct and enum definitions inline within each contract that uses them.
Shared Functions
Functions declared at file level (outside any class) are available to all contracts:
function calculateFee(amount: number, bps: number): number {
return (amount * bps) / 10000;
}
export class Vault {
withdraw(amount: number): void {
let fee: number = calculateFee(amount, 50);
// ...
}
}
Standalone functions are included as internal functions in every contract that references them. Arrow functions work the same way:
const calculateFee = (amount: number, bps: number): number => {
return (amount * bps) / 10000;
};
Shared Constants
Constants declared at file level are inlined into expressions:
const MAX_FEE = 500;
const FEE_DENOMINATOR = 10000;
export class Vault {
withdraw(amount: number): void {
let fee: number = (amount * MAX_FEE) / FEE_DENOMINATOR;
// MAX_FEE and FEE_DENOMINATOR are inlined as literal values
}
}
How It Works
The compilation pipeline has two phases:
-
Pre scan phase: All
.tsfiles in the contracts directory are scanned to collect:- Interfaces → struct definitions
- Enums → enum definitions
- File level functions → shared function definitions
- File level
constdeclarations → constant values
-
Compilation phase: Each contract file is parsed with access to all shared definitions from the pre scan. This means contracts can reference types, functions, and constants from any other file without explicit import resolution at the Solidity level.
Cache Invalidation
The incremental compilation cache tracks shared definitions separately. If any shared type, function, or constant changes, all dependent contracts are automatically recompiled. See Incremental Compilation for details.