use of org.lflang.lf.Import in project lingua-franca by lf-lang.
the class GeneratorUtils method validate.
/**
* Validate the files containing reactors in the given
* {@code instantiationGraph}. If a file is imported by
* another file in the instantiation graph, propagate the
* resulting errors to the importing file.
* @param context The context providing the cancel
* indicator used by the validator.
* @param fileConfig The file system configuration.
* @param instantiationGraph A DAG containing all
* reactors of interest.
* @param errorReporter An error acceptor.
*/
public static void validate(IGeneratorContext context, FileConfig fileConfig, InstantiationGraph instantiationGraph, ErrorReporter errorReporter) {
// NOTE: This method was previously misnamed validateImports.
// It validates all files, including the main file that does the importing.
// Also, it is now the only invocation of validation during code generation,
// and yet it used to only report errors in the files doing the importing.
IResourceValidator validator = ((XtextResource) fileConfig.resource).getResourceServiceProvider().getResourceValidator();
HashSet<Resource> bad = new HashSet<>();
HashSet<Resource> visited = new HashSet<>();
// levels.
for (Reactor reactor : instantiationGraph.nodesInTopologicalOrder()) {
Resource resource = reactor.eResource();
if (visited.contains(resource))
continue;
visited.add(resource);
List<Issue> issues = validator.validate(resource, CheckMode.ALL, context.getCancelIndicator());
if (bad.contains(resource) || issues.size() > 0) {
// Report the error on this resource.
Path path = null;
try {
path = FileUtil.toPath(resource);
} catch (IOException e) {
// Not sure if this is what we want.
path = Paths.get("Unknown file");
}
for (Issue issue : issues) {
errorReporter.reportError(path, issue.getLineNumber(), issue.getMessage());
}
// Report errors on resources that import this one.
for (Reactor downstreamReactor : instantiationGraph.getDownstreamAdjacentNodes(reactor)) {
for (Import importStatement : ((Model) downstreamReactor.eContainer()).getImports()) {
// FIXME: This will report the error on ALL import statements in
// file doing the importing, not just the one importing this resource.
// I have no idea how to determine which import statement is the right one.
errorReporter.reportError(importStatement, String.format("Unresolved compilation issues in '%s': " + issues.toString(), importStatement.getImportURI()));
bad.add(downstreamReactor.eResource());
}
}
}
}
}
use of org.lflang.lf.Import in project lingua-franca by lf-lang.
the class LFScopeProviderImpl method getScopeForReactorDecl.
/**
* @param obj Instantiation or Reactor that has a ReactorDecl to resolve.
* @param reference The reference to link to a ReactorDecl node.
*/
protected IScope getScopeForReactorDecl(EObject obj, EReference reference) {
// Find the local Model
Model model = null;
EObject container = obj;
while (model == null && container != null) {
container = container.eContainer();
if (container instanceof Model) {
model = (Model) container;
}
}
if (model == null) {
return Scopes.scopeFor(emptyList());
}
// Collect eligible candidates, all of which are local (i.e., not in other files).
var locals = new ArrayList<ReactorDecl>(model.getReactors());
// or directly to the reactor definition.
for (Import it : model.getImports()) {
for (ImportedReactor ir : it.getReactorClasses()) {
if (ir.getName() != null) {
locals.add(ir);
} else if (ir.getReactorClass() != null) {
locals.add(ir.getReactorClass());
}
}
}
return Scopes.scopeFor(locals);
}
Aggregations