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

org.ssssssss.script.parsing.ast.linq.LinqSelect Maven / Gradle / Ivy

The newest version!
package org.ssssssss.script.parsing.ast.linq;

import org.ssssssss.script.MagicScriptError;
import org.ssssssss.script.compile.MagicScriptCompiler;
import org.ssssssss.script.parsing.Span;
import org.ssssssss.script.parsing.ast.Expression;
import org.ssssssss.script.parsing.ast.Literal;
import org.ssssssss.script.runtime.Variables;
import org.ssssssss.script.runtime.function.MagicScriptLambdaFunction;
import org.ssssssss.script.runtime.linq.LinQBuilder;

import java.util.List;

public class LinqSelect extends Expression {

	private final List fields;

	private final LinqField from;

	private final List joins;

	private final LinqExpression where;

	private final List groups;

	private final LinqExpression having;

	private final List orders;

	private final Expression limit;

	private final Expression offset;


	public LinqSelect(Span span, List fields, LinqField from, List joins, LinqExpression where, List groups, LinqExpression having, List orders, Expression limit, Expression offset) {
		super(span);
		this.fields = fields;
		this.from = from;
		this.joins = joins;
		this.where = where;
		this.groups = groups;
		this.having = having;
		this.orders = orders;
		this.limit = limit;
		this.offset = offset;
		if(from.getVarIndex() == null){
			MagicScriptError.error("LINQ中,别名是必须的", from.getSpan());
		}
	}

	@Override
	public void visitMethod(MagicScriptCompiler compiler) {
		from.visitMethod(compiler);
		fields.forEach(it -> it.visitMethod(compiler));
		joins.forEach(it -> it.visitMethod(compiler));
		groups.forEach(it -> it.visitMethod(compiler));
		orders.forEach(it -> it.visitMethod(compiler));
		if (where != null) {
			where.visitMethod(compiler);
		}
		if (having != null) {
			having.visitMethod(compiler);
		}
		if (limit != null) {
			limit.visitMethod(compiler);
		}
		if (offset != null) {
			offset.visitMethod(compiler);
		}
	}

	@Override
	public void compile(MagicScriptCompiler compiler) {
		compiler.load2()
				.invoke(INVOKESTATIC, LinQBuilder.class, "create", LinQBuilder.class, Variables.class)
				.visit(from.getExpression())
				.visitInt(from.getVarIndex().getIndex())
				.invoke(INVOKEVIRTUAL, LinQBuilder.class, "from", LinQBuilder.class, Object.class, int.class);
		if (where != null) {
			compiler.visit(where)
					.invoke(INVOKEVIRTUAL, LinQBuilder.class, "where", LinQBuilder.class, MagicScriptLambdaFunction.class);
		}
		if (having != null) {
			compiler.visit(having)
					.invoke(INVOKEVIRTUAL, LinQBuilder.class, "having", LinQBuilder.class, MagicScriptLambdaFunction.class);
		}
		groups.forEach(group -> compiler.visit(group)
				.invoke(INVOKEVIRTUAL, LinQBuilder.class, "group", LinQBuilder.class, MagicScriptLambdaFunction.class));
		joins.forEach(compiler::visit);
		fields.forEach(field -> compiler.visit(field)
				.ldc(field.getAlias())
				.visitInt(field.getVarIndex() == null ? -1 : field.getVarIndex().getIndex())
				.invoke(INVOKEVIRTUAL, LinQBuilder.class, "select", LinQBuilder.class, MagicScriptLambdaFunction.class, String.class, int.class));
		orders.forEach(order -> compiler.visit(order)
				.visitInt(order.getOrder())
				.invoke(INVOKEVIRTUAL, LinQBuilder.class, "order", LinQBuilder.class, MagicScriptLambdaFunction.class, int.class));
		if(limit != null){
			if(offset == null && limit instanceof Literal && "1".equals(limit.getSpan().getText())){
				compiler.invoke(INVOKEVIRTUAL, LinQBuilder.class, "executeAndFetchFirst", Object.class);
				return;
			}
			compiler.visit(limit)
					.invoke(INVOKEVIRTUAL, LinQBuilder.class, "limit", LinQBuilder.class, Object.class);
			if(offset != null){
				compiler.visit(offset)
						.invoke(INVOKEVIRTUAL, LinQBuilder.class, "offset", LinQBuilder.class, Object.class);
			}
		}
		compiler.invoke(INVOKEVIRTUAL, LinQBuilder.class, "execute", List.class);
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy