/*
* ******************************************************************************
* MontiCore Language Workbench
* Copyright (c) 2015, MontiCore, All rights reserved.
*
* This project is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3.0 of the License, or (at your option) any later version.
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this project. If not, see <http://www.gnu.org/licenses/>.
* ******************************************************************************
*/
package de.monticore;
import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import org.codehaus.groovy.control.customizers.ImportCustomizer;
import com.google.common.base.Joiner;
import com.google.common.collect.Lists;
import com.google.common.io.Resources;
import de.monticore.codegen.GeneratorHelper;
import de.monticore.codegen.cd2java.ast.AstGenerator;
import de.monticore.codegen.cd2java.ast.CdDecorator;
import de.monticore.codegen.cd2java.ast_emf.CdEmfDecorator;
import de.monticore.codegen.cd2java.cocos.CoCoGenerator;
import de.monticore.codegen.cd2java.od.ODGenerator;
import de.monticore.codegen.cd2java.types.TypeResolverGenerator;
import de.monticore.codegen.cd2java.visitor.VisitorGenerator;
import de.monticore.codegen.mc2cd.MC2CDTransformation;
import de.monticore.codegen.mc2cd.MCGrammarSymbolTableHelper;
import de.monticore.codegen.parser.ParserGenerator;
import de.monticore.codegen.symboltable.SymbolTableGenerator;
import de.monticore.codegen.symboltable.SymbolTableGeneratorBuilder;
import de.monticore.codegen.symboltable.SymbolTableGeneratorHelper;
import de.monticore.generating.templateengine.GlobalExtensionManagement;
import de.monticore.generating.templateengine.reporting.Reporting;
import de.monticore.generating.templateengine.reporting.commons.ReportingConstants;
import de.monticore.generating.templateengine.reporting.reporter.InputOutputFilesReporter;
import de.monticore.grammar.cocos.GrammarCoCos;
import de.monticore.grammar.grammar._ast.ASTMCGrammar;
import de.monticore.grammar.grammar_withconcepts._cocos.Grammar_WithConceptsCoCoChecker;
import de.monticore.grammar.symboltable.MCGrammarSymbol;
import de.monticore.grammar.symboltable.MontiCoreGrammarLanguage;
import de.monticore.grammar.symboltable.MontiCoreGrammarSymbolTableCreator;
import de.monticore.incremental.IncrementalChecker;
import de.monticore.io.paths.IterablePath;
import de.monticore.io.paths.ModelPath;
import de.monticore.symboltable.GlobalScope;
import de.monticore.symboltable.ResolvingConfiguration;
import de.monticore.umlcd4a.CD4AnalysisLanguage;
import de.monticore.umlcd4a.cd4analysis._ast.ASTCDCompilationUnit;
import de.monticore.umlcd4a.symboltable.CD4AnalysisSymbolTableCreator;
import de.monticore.umlcd4a.symboltable.CDSymbol;
import de.se_rwth.commons.Joiners;
import de.se_rwth.commons.Names;
import de.se_rwth.commons.configuration.Configuration;
import de.se_rwth.commons.groovy.GroovyInterpreter;
import de.se_rwth.commons.groovy.GroovyRunner;
import de.se_rwth.commons.groovy.GroovyRunnerBase;
import de.se_rwth.commons.logging.Log;
import groovy.lang.Script;
import parser.MCGrammarParser;
/**
* The actual top level functional implementation of MontiCore. This is the
* top-most interface of MontiCore. The static members of this class constitute
* the functional API of MontiCore to be used from within Groovy scripts (by
* default). They represent the main functional blocks which make up the
* MontiCore functionality, i.e. parsing of grammar files, generation of ASTs,
* generation of parsers, etc. They also provide logging methods for from within
* a Groovy script.<br>
* <br>
* This class extends {@link Script} for the purpose of being used as a base
* class for Groovy scripts. This allows to use Groovy scripts for controlling
* the actual workflow(s) in contrast to statically compiled Java byte code.
* Language developers can hence very easily implement their own language
* processing workflows without having to recompile things.
*
* @author Galina Volkova, Andreas Horst
*/
public class MontiCoreScript extends Script implements GroovyRunner {
/* The logger name for logging from within a Groovy script. */
static final String LOG_ID = "MAIN";
private final CD4AnalysisLanguage cd4AnalysisLanguage = new CD4AnalysisLanguage();
/**
* Executes the default MontiCore Groovy script (parses grammars, generates
* ASTs, parsers, etc.).
*
* @see Configuration
* @param configuration of MontiCore for this execution
* @see Configuration
*/
public void run(Configuration configuration) {
try {
ClassLoader l = MontiCoreScript.class.getClassLoader();
String script = Resources.asCharSource(l.getResource("de/monticore/monticore_emf.groovy"),
Charset.forName("UTF-8")).read();
run(script, configuration);
}
catch (IOException e) {
Log.error("0xA1015 Failed to default MontiCore script.", e);
}
}
/**
* Executes the given Groovy script with the given
* {@link MontiCoreConfiguration}.
*
* @see Configuration
* @param configuration of MontiCore for this execution
* @param script to execute (NOT file or path, the actual Groovy source code)
*/
@Override
public void run(String script, Configuration configuration) {
/* Note to coders: this method is implemented here to allow usage of this
* class as Groovy runner; even though in fact the class
* MontiCoreScript.Runner does all the work. Letting MontiCore script also
* be an implementation of the GroovyRunner interface allows for better
* integration with the se-groovy-maven-plugin. This method should do
* nothing more than simple delegation to the MontiCoreScript.Runner. */
new Runner().run(script, configuration);
}
/**
* Parses the given grammar file.
*
* @param grammar - path to the grammar file
* @return grammar AST
*/
public Optional<ASTMCGrammar> parseGrammar(Path grammar) {
if (!grammar.toFile().isFile()) {
error("0xA1016 Cannot read " + grammar.toString() + " as it is not a file.");
}
return MCGrammarParser.parse(grammar);
}
/**
* Parses all grammars in the given {@link IterablePath}.
*
* @param grammarPath set of file and directory entries which are/contain
* grammar files to be parsed
* @return list of all successfully created grammar ASTs
*/
public List<ASTMCGrammar> parseGrammars(IterablePath grammarPath) {
List<ASTMCGrammar> result = Lists.newArrayList();
Iterator<Path> grammarPathIt = grammarPath.getResolvedPaths();
while (grammarPathIt.hasNext()) {
Path it = grammarPathIt.next();
Optional<ASTMCGrammar> ast = parseGrammar(it);
if (!ast.isPresent()) {
error("0xA1017 Failed to parse " + it.toString());
}
else {
result.add(ast.get());
}
}
return result;
}
protected MontiCoreConfiguration __configuration;
protected Iterator<Path> grammarIterator;
protected GlobalExtensionManagement glex;
protected GlobalScope symbolTable;
protected Map<ASTMCGrammar, ASTCDCompilationUnit> firstPassGrammars;
public void initGlobals(MontiCoreConfiguration configuration) {
this.__configuration = configuration;
IncrementalChecker.initialize(configuration.getOut());
enableReporting();
this.grammarIterator = configuration.getGrammars().getResolvedPaths();
this.glex = new GlobalExtensionManagement();
this.symbolTable = initSymbolTable(configuration.getModelPath());
this.firstPassGrammars = new LinkedHashMap<>();
}
protected void storeCDForGrammar(ASTMCGrammar grammar, ASTCDCompilationUnit cdAst) {
this.firstPassGrammars.put(grammar, cdAst);
}
protected ASTCDCompilationUnit getCDOfParsedGrammar(ASTMCGrammar grammar) {
return this.firstPassGrammars.get(grammar);
}
protected Iterable<ASTMCGrammar> getParsedGrammars() {
return this.firstPassGrammars.keySet();
}
public boolean isUpToDate(Path grammar) {
return IncrementalChecker.isUpToDate(grammar, __configuration.getOut(),
__configuration.getModelPath(), __configuration.getHandcodedPath());
}
public void cleanUp(Path grammar) {
IncrementalChecker.cleanUp(grammar);
}
/**
* Generates the parser for the given grammar.
*
* @param grammar to generate the parser for
* @param symbolTable
* @param outputDirectory output directory for generated Java code
*/
public void generateParser(GlobalExtensionManagement glex, ASTMCGrammar grammar, GlobalScope symbolTable,
IterablePath handcodedPath, File outputDirectory) {
Log.errorIfNull(
grammar,
"0xA4038 Parser generation can't be processed: the reference to the grammar ast is null");
ParserGenerator.generateParser(glex, grammar, symbolTable, handcodedPath, outputDirectory);
}
/**
* Generates the model language infrastructure for the given grammar (e.g.,
* modeling language, model loader, symbols, symbol kinds, etc.)
*
* @param astGrammar to generate the parser for
* @param symbolTable
* @param astCd
* @param outputDirectory output directory for generated Java code
*/
public void generateSymbolTable(ASTMCGrammar astGrammar, GlobalScope symbolTable,
ASTCDCompilationUnit astCd,
File outputDirectory, IterablePath handcodedPath) {
Log.errorIfNull(astGrammar);
SymbolTableGeneratorHelper genHelper = new SymbolTableGeneratorHelper(astGrammar, symbolTable, astCd);
SymbolTableGenerator symbolTableGenerator = new SymbolTableGeneratorBuilder().build();
symbolTableGenerator.generate(astGrammar, genHelper, outputDirectory, handcodedPath);
}
/**
* @param astClassDiagram
* @param glex
* @param globalScope
* @param outputDirectory
* @param templatePath
*/
public void generateTypeResolvers(GlobalExtensionManagement glex, GlobalScope globalScope,
ASTCDCompilationUnit astClassDiagram, File outputDirectory, IterablePath templatePath) {
VisitorGenerator.generate(glex, globalScope, astClassDiagram, outputDirectory);
TypeResolverGenerator.generate(glex, globalScope, astClassDiagram, outputDirectory);
}
/**
* TODO: Write me! TODO: doc that the grammar AST reference might change
*
* @param ast
* @return
*/
public ASTMCGrammar createSymbolsFromAST(GlobalScope globalScope, ASTMCGrammar ast) {
// Build grammar symbol table (if not already built)
String qualifiedGrammarName = Names.getQualifiedName(ast.getPackage(), ast.getName());
Optional<MCGrammarSymbol> grammarSymbol = globalScope
.<MCGrammarSymbol> resolveDown(qualifiedGrammarName, MCGrammarSymbol.KIND);
ASTMCGrammar result = ast;
if (grammarSymbol.isPresent()) {
result = (ASTMCGrammar) grammarSymbol.get().getAstNode().get();
}
else {
MontiCoreGrammarLanguage language = new MontiCoreGrammarLanguage();
ResolvingConfiguration resolvingConfiguration = new ResolvingConfiguration();
resolvingConfiguration.addTopScopeResolvers(language.getResolvingFilters());
MontiCoreGrammarSymbolTableCreator stCreator = language.getSymbolTableCreator(resolvingConfiguration,
globalScope).get();
stCreator.createFromAST(result);
globalScope.cache(language.getModelLoader(), qualifiedGrammarName);
}
MCGrammarSymbol symbol = (MCGrammarSymbol) result.getSymbol().get();
for (MCGrammarSymbol it : MCGrammarSymbolTableHelper.getAllSuperGrammars(symbol)) {
if (!it.getFullName().equals(symbol.getFullName())) {
Reporting.reportOpenInputFile(null,
Paths.get(it.getFullName().replaceAll("\\.", "/").concat(".mc4")));
Reporting.reportOpenInputFile(null,
Paths.get(it.getFullName().replaceAll("\\.", "/").concat(".cd")));
}
}
return result;
}
/**
* TODO: Write me! TODO: doc that the grammar AST reference might change
*
* @param ast
* @return
*/
public ASTCDCompilationUnit createSymbolsFromAST(GlobalScope globalScope,
ASTCDCompilationUnit ast) {
// Build grammar symbol table (if not already built)
final String qualifiedCDName = Names.getQualifiedName(ast.getPackage(), ast.getCDDefinition()
.getName());
Optional<CDSymbol> cdSymbol = globalScope.<CDSymbol> resolveDown(
qualifiedCDName,
CDSymbol.KIND);
ASTCDCompilationUnit result = ast;
if (cdSymbol.isPresent() && cdSymbol.get().getEnclosingScope().getAstNode().isPresent()) {
result = (ASTCDCompilationUnit) cdSymbol.get().getEnclosingScope().getAstNode().get();
info("Used present symbol table for " + cdSymbol.get().getFullName());
}
else {
ResolvingConfiguration resolvingConfiguration = new ResolvingConfiguration();
resolvingConfiguration.addTopScopeResolvers(cd4AnalysisLanguage.getResolvingFilters());
CD4AnalysisSymbolTableCreator stCreator = cd4AnalysisLanguage.getSymbolTableCreator(resolvingConfiguration,
globalScope).get();
stCreator.createFromAST(result);
globalScope.cache(cd4AnalysisLanguage.getModelLoader(), qualifiedCDName);
}
return result;
}
public GlobalScope initSymbolTable(ModelPath modelPath) {
final MontiCoreGrammarLanguage mcLanguage = new MontiCoreGrammarLanguage();
final ResolvingConfiguration resolvingConfiguration = new ResolvingConfiguration();
resolvingConfiguration.addTopScopeResolvers(mcLanguage.getResolvingFilters());
resolvingConfiguration.addTopScopeResolvers(cd4AnalysisLanguage.getResolvingFilters());
return new GlobalScope(modelPath, Arrays.asList(mcLanguage, cd4AnalysisLanguage), resolvingConfiguration);
}
/**
* TODO: Write me!
*
* @param ast
* @param scope
*/
public void runGrammarCoCos(ASTMCGrammar ast, GlobalScope scope) {
// Run context conditions
Grammar_WithConceptsCoCoChecker checker = new GrammarCoCos().getCoCoChecker();
checker.handle(ast);
return;
}
/**
* TODO: write me!
*
* @param grammar TODO
* @param globalScope TODO
* @param outputDirectory TODO
*/
public void generateParserWrappers(GlobalExtensionManagement glex, ASTMCGrammar grammar, GlobalScope globalScope,
IterablePath targetPath,
File outputDirectory) {
Log.errorIfNull(
grammar,
"0xA4037 Generation of parser wrappers can't be processed: the reference to the grammar ast is null");
ParserGenerator.generateParserWrappers(glex, grammar, globalScope, targetPath, outputDirectory);
}
/**
* Transforms grammar AST to class diagram AST.
*
* @param astGrammar - grammar AST
* @param glex TODO
* @param targetPath TODO
*/
public ASTCDCompilationUnit transformAstGrammarToAstCd(
GlobalExtensionManagement glex, ASTMCGrammar astGrammar, GlobalScope symbolTable,
IterablePath targetPath) {
// transformation
ASTCDCompilationUnit compUnit = new MC2CDTransformation(glex)
.apply(astGrammar);
return compUnit;
}
/**
* Prints Cd4Analysis AST to the CD-file (*.cd) in the subdirectory
* {@link MontiCoreScript#DIR_REPORTS}
*
* @param astCd - the top node of the Cd4Analysis AST
* @param outputDirectory - output directory
*/
public void storeInCdFile(ASTCDCompilationUnit astCd, File outputDirectory) {
// we also store the class diagram fully qualified such that we can later on
// resolve it properly for the generation of sub languages
String subDir = Joiner.on(File.separator).join(astCd.getPackage());
String reportSubDir = Joiners.DOT.join(astCd.getPackage());
reportSubDir = reportSubDir.isEmpty()
? astCd.getCDDefinition().getName()
: reportSubDir.concat(".").concat(astCd.getCDDefinition().getName());
GeneratorHelper.prettyPrintAstCd(astCd, outputDirectory, ReportingConstants.REPORTING_DIR
+ File.separator + reportSubDir);
GeneratorHelper.prettyPrintAstCd(astCd, outputDirectory, subDir);
String fqn = Names.getQualifiedName(astCd.getPackage(), astCd.getCDDefinition().getName());
Reporting.reportOpenInputFile(outputDirectory.toPath().toAbsolutePath(),
Paths.get(fqn.replaceAll("\\.", "/").concat(".cd")));
}
/**
* Decorates class diagram AST by adding of new classes and methods using in
* ast files TODO: rephrase!
*
* @param glex - object for managing hook points, features and global
* variables
* @param astClassDiagram - class diagram AST
* @param targetPath the directory to produce output in
*/
public void decorateCd(GlobalExtensionManagement glex,
ASTCDCompilationUnit astClassDiagram, GlobalScope symbolTable, IterablePath targetPath) {
boolean emfCompatible = false;
createCdDecorator(glex, symbolTable, targetPath, emfCompatible).decorate(astClassDiagram);
}
/**
* Generates ast files for the given class diagram AST TODO: rephrase!
*
* @param glex - object for managing hook points, features and global
* variables
* @param astClassDiagram - class diagram AST
* @param outputDirectory TODO
*/
public void generate(GlobalExtensionManagement glex, GlobalScope globalScope,
ASTCDCompilationUnit astClassDiagram, File outputDirectory, IterablePath templatePath) {
boolean emfCompatible = false;
AstGenerator.generate(glex, globalScope, astClassDiagram, outputDirectory, templatePath,
emfCompatible);
VisitorGenerator.generate(glex, globalScope, astClassDiagram, outputDirectory);
CoCoGenerator.generate(glex, globalScope, astClassDiagram, outputDirectory);
ODGenerator.generate(glex, globalScope, astClassDiagram, outputDirectory);
}
/**
* Decorates class diagram AST by adding of new classes and methods using in
* ast files TODO: rephrase!
*
* @param glex - object for managing hook points, features and global
* variables
* @param astClassDiagram - class diagram AST
* @param targetPath the directory to produce output in
*/
public void decorateEmfCd(GlobalExtensionManagement glex,
ASTCDCompilationUnit astClassDiagram, GlobalScope symbolTable, IterablePath targetPath) {
boolean emfCompatible = true;
createCdDecorator(glex, symbolTable, targetPath, emfCompatible).decorate(astClassDiagram);
}
/**
* Generates ast files for the given class diagram AST TODO: rephrase!
*
* @param glex - object for managing hook points, features and global
* variables
* @param astClassDiagram - class diagram AST
* @param outputDirectory TODO
*/
public void generateEmfCompatible(GlobalExtensionManagement glex, GlobalScope globalScope,
ASTCDCompilationUnit astClassDiagram, File outputDirectory, IterablePath templatePath) {
boolean emfCompatible = true;
AstGenerator.generate(glex, globalScope, astClassDiagram, outputDirectory, templatePath,
emfCompatible);
VisitorGenerator.generate(glex, globalScope, astClassDiagram, outputDirectory);
CoCoGenerator.generate(glex, globalScope, astClassDiagram, outputDirectory);
ODGenerator.generate(glex, globalScope, astClassDiagram, outputDirectory);
}
/**
* Creates instance of the {@link CdDecorator}
*
* @param glex
* @param symbolTable
* @param targetPath
* @param emfCompatible - create the CdDecorator for the emf compatible code
* @return
*/
private CdDecorator createCdDecorator(GlobalExtensionManagement glex, GlobalScope symbolTable,
IterablePath targetPath, boolean emfCompatible) {
if (emfCompatible) {
return new CdEmfDecorator(glex, symbolTable, targetPath);
}
return new CdDecorator(glex, symbolTable, targetPath);
}
// #######################
// log functions
// #######################
public boolean isDebugEnabled() {
return Log.isDebugEnabled(LOG_ID);
}
/**
* @see Log#debug(String, String)
* @param msg
*/
public void debug(String msg) {
Log.debug(msg, LOG_ID);
}
/**
* @see Log#debug(String, Throwable, String)
* @param msg
* @param t
*/
public void debug(String msg, Throwable t) {
Log.debug(msg, t, LOG_ID);
}
/**
* @see Log#isInfoEnabled(String) TODO: Write me!
* @return
*/
public boolean isInfoEnabled() {
return Log.isInfoEnabled(LOG_ID);
}
/**
* @see Log#info(String, String)
* @param msg
*/
public void info(String msg) {
Log.info(msg, LOG_ID);
}
/**
* @see Log#info(String, Throwable, String)
* @param msg
* @param t
*/
public void info(String msg, Throwable t) {
Log.info(msg, t, LOG_ID);
}
/**
* @see Log#warn(String)
* @param msg
*/
public void warn(String msg) {
Log.warn(msg);
}
/**
* @see Log#warn(String, Throwable)
* @param msg
* @param t
*/
public void warn(String msg, Throwable t) {
Log.warn(msg, t);
}
/**
* @see Log#error(String)
* @param msg
*/
public void error(String msg) {
Log.error(msg);
}
/**
* @see Log#error(String, Throwable)
* @param msg
* @param t
*/
public void error(String msg, Throwable t) {
Log.error(msg, t);
}
/**
* @see Log#enableFailQuick(boolean)
* @param enable
*/
public void enableFailQuick(boolean enable) {
Log.enableFailQuick(enable);
}
/**
* @see Log#getErrorCount()
* @return
*/
public long getErrorCount() {
return Log.getErrorCount();
}
// #######################
// log functions
// #######################
/**
* The global reporting initialization. This method configures reporting
* (i.e., configuring the output directory and all active reporters).
*
* @param outputDir
*/
public void enableReporting() {
// TODO AHo: document!
InputOutputFilesReporter.resetModelToArtifactMap();
// ##
MontiCoreReports reports = new MontiCoreReports(__configuration.getOut().getAbsolutePath(),
__configuration.getHandcodedPath(), __configuration.getTemplatePath());
Reporting.init(__configuration.getOut().getAbsolutePath(), reports);
}
/**
* Causes the reporting system to flush its reports (i.e., to write their
* gathered reports to disk).
*
* @param ast the grammar for which to flush the reporting
*/
public void flushReporting(ASTMCGrammar ast) {
Reporting.flush(ast);
}
/**
* Disables reporting.
*
* @return the name of the model for which reporting was previously active
* @see MontiCoreScript#startReportingFor(ASTMCGrammar, Path)
*/
public String reportingOff() {
return Reporting.off();
}
/**
* Initializes reporting for a particular model (in this case grammar). This
* method also serves as an initial reporting hook for reporting the parsing
* of the main model (grammar) file.
*
* @param grammar for which to report
* @param grammarInput path to the artifact containing the grammar
* @return whether reporting is activated
*/
public boolean startReportingFor(ASTMCGrammar grammar, Path grammarInput) {
String fqn = Names.getQualifiedName(grammar.getPackage(), grammar.getName());
boolean result = Reporting.on(fqn);
Reporting.reportParseInputFile(grammarInput, fqn);
return result;
}
/**
* Reporting is done per model (in this case grammar). This method provides
* the switch to determine for which model (grammar) reporting should occur.
*
* @param grammar to report for after invokation of this method
* @return
*/
public boolean reportingFor(ASTMCGrammar grammar) {
String fqn = Names.getQualifiedName(grammar.getPackage(), grammar.getName());
return Reporting.on(fqn);
}
/**
* @see groovy.lang.Script#run()
*/
@Override
public Object run() {
return true;
}
/**
* The actual Groovy runner used by MontiCore.
*
* @author (last commit) $Author$
* @version $Revision$, $Date$
*/
public static class Runner extends GroovyRunnerBase {
/**
* The default (Java) imports for within Groovy scripts.
*/
public static final String[] DEFAULT_IMPORTS = {
"mc.grammar._ast",
"de.monticore.generating.templateengine",
"de.monticore.codegen.cd2java.ast.cddecoration",
"de.monticore.grammar.grammar._ast",
"de.monticore.symboltable",
"de.monticore.io.paths",
"de.monticore.languages.grammar" };
/**
* @see de.se_rwth.commons.groovy.GroovyRunnerBase#doRun(java.lang.String,
* de.se_rwth.commons.configuration.Configuration)
*/
@Override
protected void doRun(String script, Configuration configuration) {
GroovyInterpreter.Builder builder = GroovyInterpreter.newInterpreter()
.withScriptBaseClass(MontiCoreScript.class)
.withImportCustomizer(new ImportCustomizer().addStarImports(DEFAULT_IMPORTS));
Optional<Configuration> config = Optional.ofNullable(configuration);
if (config.isPresent()) {
MontiCoreConfiguration mcConfig = MontiCoreConfiguration.withConfiguration(config.get());
// we add the configuration object as property with a special property
// name
builder.addVariable(MontiCoreConfiguration.CONFIGURATION_PROPERTY, mcConfig);
mcConfig.getAllValues().forEach((key, value) -> builder.addVariable(key, value));
// after adding everything we override a couple of known variable
// bindings
// to have them properly typed in the script
builder.addVariable(MontiCoreConfiguration.Options.GRAMMARS.toString(),
mcConfig.getGrammars());
builder.addVariable(MontiCoreConfiguration.Options.MODELPATH.toString(),
mcConfig.getModelPath());
builder.addVariable(MontiCoreConfiguration.Options.OUT.toString(),
mcConfig.getOut());
builder.addVariable(MontiCoreConfiguration.Options.FORCE.toString(),
mcConfig.getForce());
builder.addVariable(MontiCoreConfiguration.Options.HANDCODEDPATH.toString(),
mcConfig.getHandcodedPath());
builder.addVariable(MontiCoreConfiguration.Options.TEMPLATEPATH.toString(),
mcConfig.getTemplatePath());
}
GroovyInterpreter g = builder.build();
g.evaluate(script);
}
}
}