All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.shapesecurity.shift.es2017.reducer.StrictnessReducer Maven / Gradle / Ivy

package com.shapesecurity.shift.es2017.reducer;

import com.shapesecurity.functional.data.*;
import com.shapesecurity.shift.es2017.ast.ArrowExpression;
import com.shapesecurity.shift.es2017.ast.ClassDeclaration;
import com.shapesecurity.shift.es2017.ast.ClassExpression;
import com.shapesecurity.shift.es2017.ast.Directive;
import com.shapesecurity.shift.es2017.ast.FunctionBody;
import com.shapesecurity.shift.es2017.ast.FunctionDeclaration;
import com.shapesecurity.shift.es2017.ast.FunctionExpression;
import com.shapesecurity.shift.es2017.ast.Getter;
import com.shapesecurity.shift.es2017.ast.Method;
import com.shapesecurity.shift.es2017.ast.Node;
import com.shapesecurity.shift.es2017.ast.Script;
import com.shapesecurity.shift.es2017.ast.Setter;

import javax.annotation.Nonnull;

// It is somewhat annoying (and unnecessarily slow) to have this be bottom-up instead of top-down. But it does work.
// Given a Script, the analyze method returns a set containing all ArrowExpression, FunctionDeclaration, FunctionExpression, and Script nodes which are sloppy mode. All other ArrowExpression, FunctionDeclaration, FunctionExpression, and Script nodes are strict.
public class StrictnessReducer extends MonoidalReducer> {
    public static final StrictnessReducer INSTANCE = new StrictnessReducer();

    private StrictnessReducer() {
        super(new Monoid.ImmutableSetIdentityUnion<>());
    }

    @Nonnull
    public static ImmutableSet analyze(@Nonnull Script script) {
        return Director.reduceScript(INSTANCE, script);
    }
    // Modules are always strict; it does not make sense to analyze one.

    private boolean hasStrict(@Nonnull ImmutableList directives) {
        return directives.find(d -> d.rawValue.equals("use strict")).isJust();
    }


    @Nonnull
    @Override
    public ImmutableSet reduceArrowExpression(@Nonnull ArrowExpression node, @Nonnull ImmutableSet params, @Nonnull ImmutableSet body) {
        ImmutableSet state = super.reduceArrowExpression(node, params, body);
        if ((node.body instanceof FunctionBody) && hasStrict(((FunctionBody) node.body).directives)) {
            return this.monoidClass.identity();
        }
        return state.put(node);
    }


    @Nonnull
    @Override
    public ImmutableSet reduceClassDeclaration(@Nonnull ClassDeclaration node, @Nonnull ImmutableSet name, @Nonnull Maybe> _super, @Nonnull ImmutableList> elements) {
        return this.monoidClass.identity();
    }

    @Nonnull
    @Override
    public ImmutableSet reduceClassExpression(@Nonnull ClassExpression node, @Nonnull Maybe> name, @Nonnull Maybe> _super, @Nonnull ImmutableList> elements) {
        return this.monoidClass.identity();
    }

    @Nonnull
    @Override
    public ImmutableSet reduceFunctionDeclaration(@Nonnull FunctionDeclaration node, @Nonnull ImmutableSet name, @Nonnull ImmutableSet params, @Nonnull ImmutableSet body) {
        ImmutableSet state = super.reduceFunctionDeclaration(node, name, params, body);
        if (hasStrict((node.body).directives)) {
            return this.monoidClass.identity();
        }
        return state.put(node);
    }

    @Nonnull
    @Override
    public ImmutableSet reduceFunctionExpression(@Nonnull FunctionExpression node, @Nonnull Maybe> name, @Nonnull ImmutableSet params, @Nonnull ImmutableSet body) {
        ImmutableSet state = super.reduceFunctionExpression(node, name, params, body);
        if (hasStrict((node.body).directives)) {
            return this.monoidClass.identity();
        }
        return state.put(node);
    }

    @Nonnull
    @Override
    public ImmutableSet reduceGetter(@Nonnull Getter node, @Nonnull ImmutableSet name, @Nonnull ImmutableSet body) {
        ImmutableSet state = super.reduceGetter(node, name, body);
        if (hasStrict((node.body).directives)) {
            return this.monoidClass.identity();
        }
        return state.put(node);
    }

    @Nonnull
    @Override
    public ImmutableSet reduceMethod(@Nonnull Method node, @Nonnull ImmutableSet name, @Nonnull ImmutableSet params, @Nonnull ImmutableSet body) {
        ImmutableSet state = super.reduceMethod(node, name, params, body);
        if (hasStrict((node.body).directives)) {
            return this.monoidClass.identity();
        }
        return state.put(node);
    }

    @Nonnull
    @Override
    public ImmutableSet reduceScript(@Nonnull Script node, @Nonnull ImmutableList> directives, @Nonnull ImmutableList> statements) {
        ImmutableSet state = super.reduceScript(node, directives, statements);
        if (hasStrict(node.directives)) {
            return this.monoidClass.identity();
        }
        return state.put(node);
    }

    @Nonnull
    @Override
    public ImmutableSet reduceSetter(@Nonnull Setter node, @Nonnull ImmutableSet name, @Nonnull ImmutableSet param, @Nonnull ImmutableSet body) {
        ImmutableSet state = super.reduceSetter(node, name, param, body);
        if (hasStrict((node.body).directives)) {
            return this.monoidClass.identity();
        }
        return state.put(node);
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy