package org.smoothbuild.parse; import static org.smoothbuild.lang.function.base.Name.name; import static org.smoothbuild.parse.LocationHelpers.locationOf; import java.util.HashMap; import java.util.Map; import javax.inject.Inject; import org.smoothbuild.antlr.SmoothBaseVisitor; import org.smoothbuild.antlr.SmoothParser.FunctionContext; import org.smoothbuild.antlr.SmoothParser.FunctionNameContext; import org.smoothbuild.antlr.SmoothParser.ModuleContext; import org.smoothbuild.cli.Console; import org.smoothbuild.lang.function.Functions; import org.smoothbuild.lang.function.base.Name; /** * Transforms script ParseTree into map that maps function name to its * FunctionContext. Detects illegal function names, duplicate function names, * overridden imports. */ public class FunctionsCollector { public static Map<Name, FunctionContext> collectFunctions(Console console, Functions functions, ModuleContext module) { Worker worker = new Worker(console, functions); worker.visit(module); if (console.isErrorReported()) { throw new ParsingException(); } return worker.result(); } private static class Worker extends SmoothBaseVisitor<Void> { private final Functions functions; private final Console console; private final Map<Name, FunctionContext> functionContexts; @Inject public Worker(Console console, Functions functions) { this.console = console; this.functions = functions; this.functionContexts = new HashMap<>(); } public Void visitFunction(FunctionContext functionContext) { FunctionNameContext nameContext = functionContext.functionName(); Name name = name(nameContext.getText()); if (functionContexts.keySet().contains(name)) { console.error(locationOf(nameContext), "Function " + name + " is already defined."); return null; } if (functions.contains(name)) { console.error(locationOf(nameContext), "Function " + name + " cannot override builtin function with the same name."); return null; } functionContexts.put(name, functionContext); return null; } public Map<Name, FunctionContext> result() { return functionContexts; } } }