<commit_before>/**
 * View code for expressions.
 *
 * @flow
 */
'use strict';

import React, {
    Image,
    Text,
    View,
    DeviceEventEmitter,
} from 'react-native';

import StatelessComponent from './StatelessComponent'
import {registerView} from './ViewTracker'

import type {
    ExprPath,
    PathComponent,
    UserExpression,
    UserLambda,
    UserFuncCall,
    UserVariable,
    UserReference
} from './types'

import * as t from './types'

// This is the type returned by RelativeImageStub.
type AssetId = number;

const stepPath = (exprPath: ExprPath, component: PathComponent): ExprPath => {
    return exprPath.withPathSteps(exprPath.pathSteps.push(component));
};

type ExpressionPropTypes = {
    expr: UserExpression,
    path: ExprPath,
}
class Expression extends StatelessComponent<ExpressionPropTypes> {
    render() {
        const {expr, path} = this.props;
        return t.matchUserExpression(expr, {
            userLambda: (expr) => <Lambda expr={expr} path={path} />,
            userFuncCall: (expr) => <FuncCall expr={expr} path={path} />,
            userVariable: (expr) => <Variable expr={expr} path={path} />,
            userReference: (expr) => <Reference expr={expr} path={path} />,
        });
    }
}

type LambdaPropTypes = {
    expr: UserLambda,
    path: ExprPath,
}
class Lambda extends StatelessComponent<LambdaPropTypes> {
    render() {
        const {expr, path} = this.props;
        var body;
        if (expr.body != null) {
            body = <Expression expr={expr.body}
                               path={stepPath(path, 'body')} />;
        } else {
            body = <EmptyBody path={stepPath(path, 'body')} />;
        }
        return <ExprContainer path={path}>
            <ExprText>λ</ExprText>
            <ExprText>{expr.varName}</ExprText>
            <Bracket source={require('./img/left_bracket.png')}/>
            {body}
            <Bracket source={require('./img/right_bracket.png')}/>
        </ExprContainer>;
    }
}

type FuncCallPropTypes = {
    expr: UserFuncCall,
    path: ExprPath,
}
class FuncCall extends StatelessComponent<FuncCallPropTypes> {
    render() {
        const {expr, path} = this.props;
        return <ExprContainer path={path}>
            <Expression expr={expr.func} path={stepPath(path, 'func')} />
            <Bracket source={require('./img/left_paren.png')}/>
            <Expression expr={expr.arg} path={stepPath(path, 'arg')} />
            <Bracket source={require('./img/right_paren.png')}/>
        </ExprContainer>;
    }
}

type VariablePropTypes = {
    expr: UserVariable,
    path: ExprPath,
}
class Variable extends StatelessComponent<VariablePropTypes> {
    render() {
        const {expr, path} = this.props;
        return <ExprContainer path={path}>
            <ExprText>{expr.varName}</ExprText>
        </ExprContainer>
    }
}

type ReferencePropTypes = {
    expr: UserReference,
    path: ExprPath,
}
class Reference extends StatelessComponent<ReferencePropTypes> {
    render() {
        const {expr, path} = this.props;
        return <ExprContainer path={path}>
            <ExprText>{expr.defName}</ExprText>
        </ExprContainer>
    }
}

type ExprContainerPropTypes = {
    children: any,
    path: ExprPath,
}
class ExprContainer extends StatelessComponent<ExprContainerPropTypes> {
    componentDidMount() {
        registerView(this.props.path, this.refs.viewRef);
    }

    render() {
        const {children} = this.props;
        return <View ref="viewRef" style={{
            flexDirection: 'row',
            backgroundColor: "white",
            elevation: 5,
            paddingTop: 1,
            alignItems: "center",
            paddingBottom: 1,
            paddingLeft: 2,
            paddingRight: 2,
            marginTop: 1,
            marginBottom: 1,
            marginLeft: 2,
            marginRight: 2,
        }}>
            {children}
        </View>
    }
}

type ExprTextPropTypes = {
    children: any,
}
class ExprText extends StatelessComponent<ExprTextPropTypes> {
    render() {
        const {children} = this.props;
        return <Text style={{
                paddingLeft: 6,
                paddingRight: 6,
                fontSize: 28,
                color: "black",
                textAlign: "center",
                textAlignVertical: "center",
            }}>
            {children}
        </Text>;
    }
}

type EmptyBodyPropTypes = {
    path: ExprPath,
}
class EmptyBody extends StatelessComponent<EmptyBodyPropTypes> {
    componentDidMount() {
        registerView(this.props.path, this.refs.viewRef);
    }

    render() {
        const {path} = this.props;
        return <View style={{
            backgroundColor: "#FFBBBB",
            padding: 2,
            width: 20,
            height: 40,
            margin: 1,
            alignSelf: "center",
        }}><commit_msg>Fix crash when making a lambda with an empty body<commit_after>/**
 * View code for expressions.
 *
 * @flow
 */
'use strict';

import React, {
    Image,
    Text,
    View,
    DeviceEventEmitter,
} from 'react-native';

import StatelessComponent from './StatelessComponent'
import {registerView} from './ViewTracker'

import type {
    ExprPath,
    PathComponent,
    UserExpression,
    UserLambda,
    UserFuncCall,
    UserVariable,
    UserReference
} from './types'

import * as t from './types'

// This is the type returned by RelativeImageStub.
type AssetId = number;

const stepPath = (exprPath: ExprPath, component: PathComponent): ExprPath => {
    return exprPath.withPathSteps(exprPath.pathSteps.push(component));
};

type ExpressionPropTypes = {
    expr: UserExpression,
    path: ExprPath,
}
class Expression extends StatelessComponent<ExpressionPropTypes> {
    render() {
        const {expr, path} = this.props;
        return t.matchUserExpression(expr, {
            userLambda: (expr) => <Lambda expr={expr} path={path} />,
            userFuncCall: (expr) => <FuncCall expr={expr} path={path} />,
            userVariable: (expr) => <Variable expr={expr} path={path} />,
            userReference: (expr) => <Reference expr={expr} path={path} />,
        });
    }
}

type LambdaPropTypes = {
    expr: UserLambda,
    path: ExprPath,
}
class Lambda extends StatelessComponent<LambdaPropTypes> {
    render() {
        const {expr, path} = this.props;
        var body;
        if (expr.body != null) {
            body = <Expression expr={expr.body}
                               path={stepPath(path, 'body')} />;
        } else {
            body = <EmptyBody path={stepPath(path, 'body')} />;
        }
        return <ExprContainer path={path}>
            <ExprText>λ</ExprText>
            <ExprText>{expr.varName}</ExprText>
            <Bracket source={require('./img/left_bracket.png')}/>
            {body}
            <Bracket source={require('./img/right_bracket.png')}/>
        </ExprContainer>;
    }
}

type FuncCallPropTypes = {
    expr: UserFuncCall,
    path: ExprPath,
}
class FuncCall extends StatelessComponent<FuncCallPropTypes> {
    render() {
        const {expr, path} = this.props;
        return <ExprContainer path={path}>
            <Expression expr={expr.func} path={stepPath(path, 'func')} />
            <Bracket source={require('./img/left_paren.png')}/>
            <Expression expr={expr.arg} path={stepPath(path, 'arg')} />
            <Bracket source={require('./img/right_paren.png')}/>
        </ExprContainer>;
    }
}

type VariablePropTypes = {
    expr: UserVariable,
    path: ExprPath,
}
class Variable extends StatelessComponent<VariablePropTypes> {
    render() {
        const {expr, path} = this.props;
        return <ExprContainer path={path}>
            <ExprText>{expr.varName}</ExprText>
        </ExprContainer>
    }
}

type ReferencePropTypes = {
    expr: UserReference,
    path: ExprPath,
}
class Reference extends StatelessComponent<ReferencePropTypes> {
    render() {
        const {expr, path} = this.props;
        return <ExprContainer path={path}>
            <ExprText>{expr.defName}</ExprText>
        </ExprContainer>
    }
}

type ExprContainerPropTypes = {
    children: any,
    path: ExprPath,
}
class ExprContainer extends StatelessComponent<ExprContainerPropTypes> {
    componentDidMount() {
        registerView(this.props.path, this.refs.viewRef);
    }

    render() {
        const {children} = this.props;
        return <View ref="viewRef" style={{
            flexDirection: 'row',
            backgroundColor: "white",
            elevation: 5,
            paddingTop: 1,
            alignItems: "center",
            paddingBottom: 1,
            paddingLeft: 2,
            paddingRight: 2,
            marginTop: 1,
            marginBottom: 1,
            marginLeft: 2,
            marginRight: 2,
        }}>
            {children}
        </View>
    }
}

type ExprTextPropTypes = {
    children: any,
}
class ExprText extends StatelessComponent<ExprTextPropTypes> {
    render() {
        const {children} = this.props;
        return <Text style={{
                paddingLeft: 6,
                paddingRight: 6,
                fontSize: 28,
                color: "black",
                textAlign: "center",
                textAlignVertical: "center",
            }}>
            {children}
        </Text>;
    }
}

type EmptyBodyPropTypes = {
    path: ExprPath,
}
class EmptyBody extends StatelessComponent<EmptyBodyPropTypes> {
    componentDidMount() {
        registerView(this.props.path, this.refs.viewRef);
    }

    render() {
        return <View ref="viewRef" style={{
            backgroundColor: "#FFBBBB",
            padding: 2,
            width: 20,
            height: 40,
            margin: 1,
            alignSelf: "center",
        }}>
{'fraction_non_alphanumeric': 0.12670146351448164, 'fraction_numerical': 0.0038890594616722957, 'mean_word_length': 2.1976439790575917, 'pattern_counts': {'":': 0, '<': 85, '<?xml version=': 0, '>': 95, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6665606', 'n_tokens_mistral': 2863, 'n_tokens_neox': 2800, 'n_words': 635}