/**
 * @license
 * Copyright Google Inc. All Rights Reserved.
 *
 * Use of this source code is governed by an MIT-style license that can be
 * found in the LICENSE file at https://angular.io/license
 */
/// <amd-module name="@angular/compiler-cli/src/ngtsc/metadata/src/resolver" />
/**
 * resolver.ts implements partial computation of expressions, resolving expressions to static
 * values where possible and returning a `DynamicValue` signal when not.
 */
import { Expression } from '@angular/compiler';
import * as ts from 'typescript';
import { ReflectionHost } from '../../host';
/**
 * Represents a value which cannot be determined statically.
 *
 * Use `isDynamicValue` to determine whether a `ResolvedValue` is a `DynamicValue`.
 */
export declare class DynamicValue {
    /**
     * This is needed so the "is DynamicValue" assertion of `isDynamicValue` actually has meaning.
     *
     * Otherwise, "is DynamicValue" is akin to "is {}" which doesn't trigger narrowing.
     */
    private _isDynamic;
}
/**
 * Used to test whether a `ResolvedValue` is a `DynamicValue`.
 */
export declare function isDynamicValue(value: any): value is DynamicValue;
/**
 * A value resulting from static resolution.
 *
 * This could be a primitive, collection type, reference to a `ts.Node` that declares a
 * non-primitive value, or a special `DynamicValue` type which indicates the value was not
 * available statically.
 */
export declare type ResolvedValue = number | boolean | string | null | undefined | Reference | EnumValue | ResolvedValueArray | ResolvedValueMap | DynamicValue;
/**
 * An array of `ResolvedValue`s.
 *
 * This is a reified type to allow the circular reference of `ResolvedValue` -> `ResolvedValueArray`
 * ->
 * `ResolvedValue`.
 */
export interface ResolvedValueArray extends Array<ResolvedValue> {
}
/**
 * A map of strings to `ResolvedValue`s.
 *
 * This is a reified type to allow the circular reference of `ResolvedValue` -> `ResolvedValueMap` ->
 * `ResolvedValue`.
 */ export interface ResolvedValueMap extends Map<string, ResolvedValue> {
}
/**
 * A value member of an enumeration.
 *
 * Contains a `Reference` to the enumeration itself, and the name of the referenced member.
 */
export declare class EnumValue {
    readonly enumRef: Reference<ts.EnumDeclaration>;
    readonly name: string;
    constructor(enumRef: Reference<ts.EnumDeclaration>, name: string);
}
export declare enum ImportMode {
    UseExistingImport = 0,
    ForceNewImport = 1
}
/**
 * A reference to a `ts.Node`.
 *
 * For example, if an expression evaluates to a function or class definition, it will be returned
 * as a `Reference` (assuming references are allowed in evaluation).
 */
export declare abstract class Reference<T extends ts.Node = ts.Node> {
    readonly node: T;
    constructor(node: T);
    /**
     * Whether an `Expression` can be generated which references the node.
     */
    readonly expressable: boolean;
    /**
     * Generate an `Expression` representing this type, in the context of the given SourceFile.
     *
     * This could be a local variable reference, if the symbol is imported, or it could be a new
     * import if needed.
     */
    abstract toExpression(context: ts.SourceFile, importMode?: ImportMode): Expression | null;
    abstract addIdentifier(identifier: ts.Identifier): void;
}
/**
 * A reference to a node only, without any ability to get an `Expression` representing that node.
 *
 * This is used for returning references to things like method declarations, which are not directly
 * referenceable.
 */
export declare class NodeReference<T extends ts.Node = ts.Node> extends Reference<T> {
    readonly moduleName: string | null;
    constructor(node: T, moduleName: string | null);
    toExpression(context: ts.SourceFile): null;
    addIdentifier(identifier: ts.Identifier): void;
}
/**
 * A reference to a node which has a `ts.Identifier` and can be resolved to an `Expression`.
 *
 * Imports generated by `ResolvedReference`s are always relative.
 */
export declare class ResolvedReference<T extends ts.Node = ts.Node> extends Reference<T> {
    protected primaryIdentifier: ts.Identifier;
    protected identifiers: ts.Identifier[];
    constructor(node: T, primaryIdentifier: ts.Identifier);
    readonly expressable = true;
    toExpression(context: ts.SourceFile, importMode?: ImportMode): Expression;
    addIdentifier(identifier: ts.Identifier): void;
}
/**
 * A reference to a node which has a `ts.Identifer` and an expected absolute module name.
 *
 * An `AbsoluteReference` can be resolved to an `Expression`, and if that expression is an import
 * the module specifier will be an absolute module name, not a relative path.
 */
export declare class AbsoluteReference<T extends ts.Node> extends Reference<T> {
    private primaryIdentifier;
    readonly moduleName: string;
    readonly symbolName: string;
    private identifiers;
    constructor(node: T, primaryIdentifier: ts.Identifier, moduleName: string, symbolName: string);
    readonly expressable = true;
    toExpression(context: ts.SourceFile, importMode?: ImportMode): Expression;
    addIdentifier(identifier: ts.Identifier): void;
}
/**
 * Statically resolve the given `ts.Expression` into a `ResolvedValue`.
 *
 * @param node the expression to statically resolve if possible
 * @param checker a `ts.TypeChecker` used to understand the expression
 * @param foreignFunctionResolver a function which will be used whenever a "foreign function" is
 * encountered. A foreign function is a function which has no body - usually the result of calling
 * a function declared in another library's .d.ts file. In these cases, the foreignFunctionResolver
 * will be called with the function's declaration, and can optionally return a `ts.Expression`
 * (possibly extracted from the foreign function's type signature) which will be used as the result
 * of the call.
 * @returns a `ResolvedValue` representing the resolved value
 */
export declare function staticallyResolve(node: ts.Expression, host: ReflectionHost, checker: ts.TypeChecker, foreignFunctionResolver?: (node: Reference<ts.FunctionDeclaration | ts.MethodDeclaration>, args: ts.Expression[]) => ts.Expression | null): ResolvedValue;
