Search in sources :

Example 1 with Target

use of org.lflang.Target in project lingua-franca by lf-lang.

the class GeneratorBase method doGenerate.

/**
 * Generate code from the Lingua Franca model contained by the specified resource.
 *
 * This is the main entry point for code generation. This base class finds all
 * reactor class definitions, including any reactors defined in imported .lf files
 * (except any main reactors in those imported files), and adds them to the
 * {@link #GeneratorBase.reactors reactors} list. If errors occur during
 * generation, then a subsequent call to errorsOccurred() will return true.
 * @param resource The resource containing the source code.
 * @param context Context relating to invocation of the code generator.
 * In stand alone mode, this object is also used to relay CLI arguments.
 */
public void doGenerate(Resource resource, LFGeneratorContext context) {
    GeneratorUtils.setTargetConfig(context, GeneratorUtils.findTarget(fileConfig.resource), targetConfig, errorReporter);
    cleanIfNeeded(context);
    printInfo(context.getMode());
    // Markers mark problems in the Eclipse IDE when running in integrated mode.
    if (errorReporter instanceof EclipseErrorReporter) {
        ((EclipseErrorReporter) errorReporter).clearMarkers();
    }
    ASTUtils.setMainName(fileConfig.resource, fileConfig.name);
    createMainInstantiation();
    // Check if there are any conflicting main reactors elsewhere in the package.
    if (Objects.equal(context.getMode(), LFGeneratorContext.Mode.STANDALONE) && mainDef != null) {
        for (String conflict : new MainConflictChecker(fileConfig).conflicts) {
            errorReporter.reportError(this.mainDef.getReactorClass(), "Conflicting main reactor in " + conflict);
        }
    }
    // Configure the command factory
    commandFactory.setVerbose();
    if (Objects.equal(context.getMode(), LFGeneratorContext.Mode.STANDALONE) && context.getArgs().containsKey("quiet")) {
        commandFactory.setQuiet();
    }
    // This must be done before desugaring delays below.
    analyzeFederates(context);
    // Process target files. Copy each of them into the src-gen dir.
    // FIXME: Should we do this here? This doesn't make sense for federates the way it is
    // done here.
    copyUserFiles(this.targetConfig, this.fileConfig);
    // Collect reactors and create an instantiation graph.
    // These are needed to figure out which resources we need
    // to validate, which happens in setResources().
    setReactorsAndInstantiationGraph(context.getMode());
    GeneratorUtils.validate(context, fileConfig, instantiationGraph, errorReporter);
    List<Resource> allResources = GeneratorUtils.getResources(reactors);
    resources.addAll(// FIXME: This filter reproduces the behavior of the method it replaces. But why must it be so complicated? Why are we worried about weird corner cases like this?
    allResources.stream().filter(it -> !Objects.equal(it, fileConfig.resource) || mainDef != null && it == mainDef.getReactorClass().eResource()).map(it -> GeneratorUtils.getLFResource(it, fileConfig.getSrcGenBasePath(), context, errorReporter)).collect(Collectors.toList()));
    GeneratorUtils.accommodatePhysicalActionsIfPresent(allResources, getTarget().setsKeepAliveOptionAutomatically(), targetConfig, errorReporter);
    // FIXME: Should the GeneratorBase pull in `files` from imported
    // resources?
    // Reroute connections that have delays associated with them via
    // generated delay reactors.
    transformDelays();
    // Transform connections that reside in mutually exclusive modes and are otherwise conflicting
    // This should be done before creating the instantiation graph
    transformConflictingConnectionsInModalReactors();
    // Invoke these functions a second time because transformations
    // may have introduced new reactors!
    setReactorsAndInstantiationGraph(context.getMode());
    // Check for existence and support of modes
    hasModalReactors = IterableExtensions.exists(reactors, it -> !it.getModes().isEmpty());
    checkModalReactorSupport(false);
    enableSupportForSerializationIfApplicable(context.getCancelIndicator());
}
Also used : SupportedSerializers(org.lflang.federated.serialization.SupportedSerializers) Delay(org.lflang.lf.Delay) FedASTUtils(org.lflang.federated.FedASTUtils) Action(org.lflang.lf.Action) InferredType(org.lflang.InferredType) Matcher(java.util.regex.Matcher) Map(java.util.Map) Instantiation(org.lflang.lf.Instantiation) Objects(com.google.common.base.Objects) Path(java.nio.file.Path) Connection(org.lflang.lf.Connection) MainConflictChecker(org.lflang.MainConflictChecker) TargetConfig(org.lflang.TargetConfig) Collection(java.util.Collection) Set(java.util.Set) EObject(org.eclipse.emf.ecore.EObject) Collectors(java.util.stream.Collectors) Parameter(org.lflang.lf.Parameter) List(java.util.List) Value(org.lflang.lf.Value) CollectionLiterals(org.eclipse.xtext.xbase.lib.CollectionLiterals) Target(org.lflang.Target) Resource(org.eclipse.emf.ecore.resource.Resource) Pattern(java.util.regex.Pattern) Pair(org.eclipse.xtext.xbase.lib.Pair) FileConfig(org.lflang.FileConfig) ASTUtils(org.lflang.ASTUtils) FederateInstance(org.lflang.federated.FederateInstance) Iterables(com.google.common.collect.Iterables) LfFactory(org.lflang.lf.LfFactory) ErrorReporter(org.lflang.ErrorReporter) AbstractLFValidator(org.lflang.validation.AbstractLFValidator) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) LinkedHashMap(java.util.LinkedHashMap) CancelIndicator(org.eclipse.xtext.util.CancelIndicator) Reaction(org.lflang.lf.Reaction) TimeUnit(org.lflang.TimeUnit) TimeValue(org.lflang.TimeValue) LinkedHashSet(java.util.LinkedHashSet) IMarker(org.eclipse.core.resources.IMarker) InstantiationGraph(org.lflang.graph.InstantiationGraph) CoordinationType(org.lflang.TargetProperty.CoordinationType) Model(org.lflang.lf.Model) IOException(java.io.IOException) Time(org.lflang.lf.Time) File(java.io.File) IteratorExtensions(org.eclipse.xtext.xbase.lib.IteratorExtensions) IterableExtensions(org.eclipse.xtext.xbase.lib.IterableExtensions) Paths(java.nio.file.Paths) Reactor(org.lflang.lf.Reactor) VarRef(org.lflang.lf.VarRef) MainConflictChecker(org.lflang.MainConflictChecker) Resource(org.eclipse.emf.ecore.resource.Resource)

Example 2 with Target

use of org.lflang.Target in project lingua-franca by lf-lang.

the class LFGenerator method doGenerate.

@Override
public void doGenerate(Resource resource, IFileSystemAccess2 fsa, IGeneratorContext context) {
    final LFGeneratorContext lfContext = LFGeneratorContext.lfGeneratorContextOf(context, resource);
    // The fastest way to generate code is to not generate any code.
    if (lfContext.getMode() == LFGeneratorContext.Mode.LSP_FAST)
        return;
    final Target target = Target.fromDecl(ASTUtils.targetDecl(resource));
    assert target != null;
    FileConfig fileConfig;
    try {
        fileConfig = Objects.requireNonNull(createFileConfig(target, resource, fsa, lfContext));
    } catch (IOException e) {
        throw new RuntimeIOException("Error during FileConfig instantiation", e);
    }
    final ErrorReporter errorReporter = lfContext.constructErrorReporter(fileConfig);
    final GeneratorBase generator = createGenerator(target, fileConfig, errorReporter);
    if (generator != null) {
        generator.doGenerate(resource, lfContext);
        generatorErrorsOccurred = generator.errorsOccurred();
    }
    if (errorReporter instanceof LanguageServerErrorReporter) {
        ((LanguageServerErrorReporter) errorReporter).publishDiagnostics();
    }
}
Also used : FileConfig(org.lflang.FileConfig) RuntimeIOException(org.eclipse.xtext.util.RuntimeIOException) Target(org.lflang.Target) ErrorReporter(org.lflang.ErrorReporter) IOException(java.io.IOException) RuntimeIOException(org.eclipse.xtext.util.RuntimeIOException)

Example 3 with Target

use of org.lflang.Target in project lingua-franca by lf-lang.

the class TestBase method runTestsFor.

/**
 * Run tests in the given selection for a subset of given targets.
 *
 * @param subset The subset of targets to run the selected tests for.
 * @param description A string that describes the collection of tests.
 * @param selected A predicate that given a test category returns whether
 * it should be included in this test run or not.
 * @param configurator A procedure for configuring the tests.
 * @param level The level of testing to be performed during this run.
 * @param copy Whether to work on copies of tests in the test.
 * registry.
 */
protected void runTestsFor(List<Target> subset, String description, Predicate<TestCategory> selected, Configurator configurator, TestLevel level, boolean copy) {
    for (Target target : subset) {
        printTestHeader(target, description);
        runTestsAndPrintResults(target, selected, configurator, level, copy);
    }
}
Also used : Target(org.lflang.Target)

Example 4 with Target

use of org.lflang.Target in project lingua-franca by lf-lang.

the class LinguaFrancaValidationTest method testPreambleVisibility.

/**
 * Test warnings and errors for the target dependent preamble visibility qualifiers
 */
@Test
public void testPreambleVisibility() throws Exception {
    for (Target target : Target.values()) {
        for (Visibility visibility : Visibility.values()) {
            // Java 17:
            // Model model_reactor_scope = """
            // target %s;
            // reactor Foo {
            // %spreamble {==}
            // }
            // """.formatted(target, visibility != java.beans.Visibility.NONE ? visibility + " " : "");
            // Java 11:
            Model model_reactor_scope = parseWithoutError(String.join(System.getProperty("line.separator"), String.format("target %s;", target), "reactor Foo {", String.format("    %spreamble {==}", visibility != Visibility.NONE ? visibility + " " : ""), "}"));
            // Java 17:
            // Model model_file_scope = """
            // target %s;
            // %spreamble {==}
            // reactor Foo {
            // }
            // """.formatted(target, visibility != java.beans.Visibility.NONE ? visibility + " " : "");
            // Java 11:
            Model model_file_scope = parseWithoutError(String.join(System.getProperty("line.separator"), String.format("target %s;", target), String.format("    %spreamble {==}", visibility != Visibility.NONE ? visibility + " " : ""), "reactor Foo {", "}"));
            // Java 17:
            // Model model_no_preamble = """
            // target %s;
            // reactor Foo {
            // }
            // """.formatted(target);
            // Java 11:
            Model model_no_preamble = parseWithoutError(String.join(System.getProperty("line.separator"), String.format("target %s;", target), "reactor Foo {", "}"));
            validator.assertNoIssues(model_no_preamble);
            if (target == Target.CPP) {
                if (visibility == Visibility.NONE) {
                    validator.assertError(model_file_scope, LfPackage.eINSTANCE.getPreamble(), null, "Preambles for the C++ target need a visibility qualifier (private or public)!");
                    validator.assertError(model_reactor_scope, LfPackage.eINSTANCE.getPreamble(), null, "Preambles for the C++ target need a visibility qualifier (private or public)!");
                } else {
                    validator.assertNoIssues(model_file_scope);
                    validator.assertNoIssues(model_reactor_scope);
                }
            } else {
                if (visibility == Visibility.NONE) {
                    validator.assertNoIssues(model_file_scope);
                    validator.assertNoIssues(model_reactor_scope);
                } else {
                    validator.assertWarning(model_file_scope, LfPackage.eINSTANCE.getPreamble(), null, String.format("The %s qualifier has no meaning for the %s target. It should be removed.", visibility, target.name()));
                    validator.assertWarning(model_reactor_scope, LfPackage.eINSTANCE.getPreamble(), null, String.format("The %s qualifier has no meaning for the %s target. It should be removed.", visibility, target.name()));
                }
            }
        }
    }
}
Also used : Target(org.lflang.Target) Model(org.lflang.lf.Model) Visibility(org.lflang.lf.Visibility) Test(org.junit.jupiter.api.Test)

Example 5 with Target

use of org.lflang.Target in project lingua-franca by lf-lang.

the class RunSingleTestMain method main.

public static void main(String[] args) throws FileNotFoundException {
    if (args.length != 1) {
        throw new IllegalArgumentException("Expected 1 path to an LF file");
    }
    var path = Paths.get(args[0]);
    if (!Files.exists(path)) {
        throw new FileNotFoundException("No such test file: " + path);
    }
    Matcher matcher = TEST_FILE_PATTERN.matcher(args[0]);
    if (!matcher.matches()) {
        throw new FileNotFoundException("Not a test: " + path);
    }
    Target target = Target.forName(matcher.group(2)).get();
    Class<? extends TestBase> testClass = getTestInstance(target);
    LFTest testCase = new LFTest(target, path.toAbsolutePath());
    TestBase.runSingleTestAndPrintResults(testCase, testClass, TestLevel.EXECUTION);
}
Also used : Target(org.lflang.Target) Matcher(java.util.regex.Matcher) FileNotFoundException(java.io.FileNotFoundException)

Aggregations

Target (org.lflang.Target)5 IOException (java.io.IOException)2 Matcher (java.util.regex.Matcher)2 ErrorReporter (org.lflang.ErrorReporter)2 FileConfig (org.lflang.FileConfig)2 Objects (com.google.common.base.Objects)1 Iterables (com.google.common.collect.Iterables)1 File (java.io.File)1 FileNotFoundException (java.io.FileNotFoundException)1 Path (java.nio.file.Path)1 Paths (java.nio.file.Paths)1 ArrayList (java.util.ArrayList)1 Collection (java.util.Collection)1 HashSet (java.util.HashSet)1 LinkedHashMap (java.util.LinkedHashMap)1 LinkedHashSet (java.util.LinkedHashSet)1 List (java.util.List)1 Map (java.util.Map)1 Set (java.util.Set)1 Pattern (java.util.regex.Pattern)1