use of mb.resource.ResourceKey in project spoofax by metaborg.
the class GenerateSourcesBuilder method buildStratego.
private void buildStratego(GenerateSourcesBuilder.Input input, Origin sdfOrigin) throws IOException, MetaborgException {
final File targetMetaborgDir = toFile(paths.targetMetaborgDir());
final File strFile = input.strFile;
final Boolean strEnabled = input.strEnabled;
if (strFile != null && strEnabled) {
require(strFile, FileExistsStamper.instance);
if (!strFile.exists()) {
throw new IOException("Main Stratego file at " + strFile + " does not exist");
}
boolean buildStrJavaStrat = input.strJavaStratPackage != null && input.strJavaStratFile != null;
if (buildStrJavaStrat) {
require(input.strJavaStratFile, FileExistsStamper.instance);
if (!input.strJavaStratFile.exists()) {
throw new IOException("Main Stratego Java strategies file at " + input.strJavaStratFile + " does not exist");
}
}
final Arguments extraArgs = new Arguments();
extraArgs.addAll(input.strjArgs);
final File outputFile;
final File depPath;
final File outputDir;
if (input.strFormat == StrategoFormat.ctree) {
outputFile = FileUtils.getFile(targetMetaborgDir, "stratego.ctree");
depPath = outputFile;
outputDir = depPath;
extraArgs.add("-F");
} else {
depPath = toFile(paths.strSrcGenJavaTransDir(input.languageId.id));
outputDir = toFile(paths.strSrcGenJavaDir());
outputFile = toFile(paths.strSrcGenJavaTransDir(input.languageId.id).resolveFile("Main.java"));
extraArgs.add("-la", "java-front");
if (buildStrJavaStrat) {
extraArgs.add("-la", input.strJavaStratPackage);
}
}
if (input.strExternalJarFlags != null) {
extraArgs.addLine(input.strExternalJarFlags);
}
final File cacheDir = toFile(paths.strCacheDir());
if (input.strategoVersion == StrategoVersion.v1) {
final Strj.Input strjInput = new Strj.Input(context, strFile, outputFile, depPath, input.strJavaPackage, true, true, input.strjIncludeDirs, input.strjIncludeFiles, Lists.newArrayList(), cacheDir, extraArgs, sdfOrigin);
final Origin strjOrigin = Strj.origin(strjInput);
requireBuild(strjOrigin);
return;
}
/*
* Make sure to require all the sdf stuff before running the stratego compiler which will search for the
* generated stratego files.
*/
requireBuild(sdfOrigin);
logger.info("> Compile Stratego code using the incremental compiler");
final File projectLocation = context.resourceService().localPath(paths.root());
assert projectLocation != null;
/*
* Make sure Pluto also understands which files Pie will require.
*/
final Set<Path> changedFiles = getChangedFiles(projectLocation);
final Set<ResourceKey> changedResources = new HashSet<>(changedFiles.size() * 2);
for (Path changedFile : changedFiles) {
require(changedFile.toFile(), FileHashStamper.instance);
changedResources.add(new FSPath(changedFile));
}
final ArrayList<IModuleImportService.ModuleIdentifier> linkedLibraries = new ArrayList<>();
final ArrayList<ResourcePath> strjIncludeDirs = new ArrayList<>();
for (File strjIncludeDir : input.strjIncludeDirs) {
FSPath fsPath = new FSPath(strjIncludeDir);
strjIncludeDirs.add(fsPath);
}
final Arguments newArgs = GenerateSourcesBuilder.splitOffLinkedLibrariesIncludeDirs(extraArgs, linkedLibraries, strjIncludeDirs, projectLocation.getPath());
final String strFileName = strFile.getName();
final String mainModuleName = strFileName.substring(0, strFileName.length() - ".str2".length());
final boolean legacyStratego = false;
final boolean isLibrary = false;
final ModuleIdentifier mainModuleIdentifier = new ModuleIdentifier(legacyStratego, isLibrary, mainModuleName, new FSPath(strFile));
final ResourcePath projectPath = new FSPath(projectLocation);
final String packageName = NameUtil.toJavaId(input.languageId.id) + ".trans";
final ResourcePath str2libReplicateDir = new FSPath(context.resourceService().localPath(paths.targetClassesDir()));
final ArrayList<Supplier<Stratego2LibInfo>> str2libraries = new ArrayList<>(input.str2libraries);
final boolean library = true;
final boolean autoImportStd = false;
final CompileInput compileInput = new CompileInput(mainModuleIdentifier, projectPath, new FSPath(outputDir), str2libReplicateDir, packageName, new FSPath(cacheDir), new ArrayList<>(0), strjIncludeDirs, linkedLibraries, newArgs, new ArrayList<>(0), library, autoImportStd, input.strategoShadowJar, input.languageId.id, str2libraries);
final Task<CompileOutput> compileTask = context.getCompileTask().createTask(compileInput);
final IPieProvider pieProvider = context.pieProvider();
final Pie pie = pieProvider.pie();
synchronized (pie) {
initCompiler(pieProvider, compileTask, depPath);
try (final MixedSession session = pie.newSession()) {
TopDownSession tdSession = session.updateAffectedBy(changedResources);
session.deleteUnobservedTasks(t -> true, (t, r) -> {
if (r != null && Objects.equals(r.getLeafExtension(), "java")) {
logger.debug("Deleting garbage from previous build: " + r);
return true;
}
return false;
});
final CompileOutput compileOutput = tdSession.getOutput(compileTask);
if (compileOutput instanceof CompileOutput.Failure) {
logger.info("> Incremental compilation of Stratego failed:");
final CompileOutput.Failure failure = (CompileOutput.Failure) compileOutput;
final ArrayList<String> notes = new ArrayList<>();
final ArrayList<String> warnings = new ArrayList<>();
final ArrayList<String> errors = new ArrayList<>();
for (Message message : failure.messages) {
switch(message.severity) {
case NOTE:
if (message.filename != null && Paths.get(new URI(message.filename)).startsWith(projectLocation.toPath())) {
if (!(message.filename.endsWith(".str") && message instanceof TypeMessage)) {
notes.add(message.toString());
}
}
break;
case WARNING:
if (message.filename != null) {
final URI uri = new URI(message.filename);
if (uri.getScheme() != null) {
if (Paths.get(uri).startsWith(projectLocation.toPath())) {
if (!(message.filename.endsWith(".str") && message instanceof TypeMessage)) {
warnings.add(message.toString());
}
}
} else {
logger.error("no uri scheme on filename of message: " + message);
}
}
break;
case ERROR:
errors.add(message.toString());
break;
}
}
for (String note : notes) {
logger.info(note);
}
for (String warning : warnings) {
logger.warn(warning);
}
for (String error : errors) {
logger.error(error);
}
throw MetaborgException.withoutStackTrace("Incremental Stratego Compilation failed with " + errors.size() + " errors.", null);
} else {
assert compileOutput instanceof CompileOutput.Success;
final CompileOutput.Success success = (CompileOutput.Success) compileOutput;
for (ResourcePath resultFile : success.resultFiles) {
final File file = context.getMbResourceService().toLocalFile(resultFile);
provide(file);
}
}
} catch (ExecException e) {
throw MetaborgException.withoutStackTrace("Incremental Stratego build failed: " + e.getMessage(), e);
} catch (InterruptedException e) {
// Ignore
} catch (URISyntaxException e) {
e.printStackTrace();
}
}
}
}
use of mb.resource.ResourceKey in project spoofax by metaborg.
the class StrategoPieAnalyzePrimitive method call.
@Override
@Nullable
protected IStrategoTerm call(IStrategoTerm current, Strategy[] svars, IStrategoTerm[] tvars, ITermFactory factory, IContext context) throws MetaborgException, IOException {
final IStrategoAppl ast = TermUtils.toApplAt(current, 0);
final String path = TermUtils.toJavaStringAt(current, 1);
// final String projectPath = TermUtils.toJavaStringAt(current, 2);
final String moduleName;
if (!(ast.getName().equals("Module") && ast.getSubtermCount() == 2)) {
moduleName = path;
} else {
moduleName = TermUtils.toJavaStringAt(ast, 0);
}
final IProject project = context.project();
if (project == null) {
logger.warn("Cannot find project for opened file, cancelling analysis. ");
return null;
}
if (languageSpecServiceProvider == null || languageServiceProvider == null || pieProviderProvider == null) {
// Indicates that meta-Spoofax is not available (ISpoofaxLanguageSpecService cannot be injected), but this
// should never happen because this primitive is inside meta-Spoofax. Check for null just in case.
logger.error("Spoofax meta services is not available; static injection failed");
return null;
}
@Nullable final ISpoofaxLanguageSpec languageSpec = getLanguageSpecification(project);
if (languageSpec == null) {
logger.warn("Cannot find language specification for project of opened file, cancelling analysis. ");
return null;
}
final ISpoofaxLanguageSpecConfig config = languageSpec.config();
final FileObject baseLoc = languageSpec.location();
final SpoofaxLangSpecCommonPaths paths = new SpoofaxLangSpecCommonPaths(baseLoc);
String strMainModule = NameUtil.toJavaId(config.strategoName().toLowerCase());
final Iterable<FileObject> strRoots = languagePathService.sourcePaths(project, SpoofaxConstants.LANG_STRATEGO_NAME);
@Nullable File strMainFile;
final FileObject strMainFileCandidate = config.strVersion().findStrMainFile(paths, strRoots, config.strategoName());
if (strMainFileCandidate != null && strMainFileCandidate.exists()) {
strMainFile = resourceService.localPath(strMainFileCandidate);
if (strMainFile == null || !strMainFile.exists()) {
logger.info("Main Stratego2 file at " + strMainFile + " does not exist");
strMainFile = resourceService.localFile(resourceService.resolve(baseLoc, path));
strMainModule = moduleName;
}
} else {
logger.info("Main Stratego2 file with name " + strMainModule + ".str2 does not exist");
strMainFile = resourceService.localFile(resourceService.resolve(baseLoc, path));
strMainModule = moduleName;
}
final File strFile = resourceService.localFile(resourceService.resolve(baseLoc, path));
@Nullable final String strExternalJarFlags = config.strExternalJarFlags();
final Iterable<FileObject> strIncludePaths = Iterables.concat(languagePathService.sourceAndIncludePaths(languageSpec, SpoofaxConstants.LANG_STRATEGO_NAME), languagePathService.sourceAndIncludePaths(languageSpec, SpoofaxConstants.LANG_STRATEGO2_NAME));
final FileObject strjIncludesReplicateDir = paths.replicateDir().resolveFile("strj-includes");
final ArrayList<ResourcePath> strjIncludeDirs = new ArrayList<>();
for (FileObject strIncludePath : strIncludePaths) {
if (!strIncludePath.exists()) {
continue;
}
if (strIncludePath.isFolder()) {
strjIncludeDirs.add(new FSPath(resourceService.localFileUpdate(strIncludePath, strjIncludesReplicateDir)));
}
}
final Arguments extraArgs = new Arguments();
extraArgs.addAll(config.strArgs());
extraArgs.add("-la", "java-front");
if (strExternalJarFlags != null) {
extraArgs.addLine(strExternalJarFlags);
}
final File projectLocation = resourceService.localPath(paths.root());
assert projectLocation != null;
final ResourcePath projectPath = new FSPath(projectLocation);
final ArrayList<Supplier<Stratego2LibInfo>> str2libraries = new ArrayList<>();
for (LanguageIdentifier sourceDep : config.sourceDeps()) {
@Nullable final ILanguageImpl sourceDepImpl = languageServiceProvider.get().getImpl(sourceDep);
if (sourceDepImpl == null) {
continue;
}
for (ILanguageComponent sourceDepImplComp : sourceDepImpl.components()) {
final String[] str2libProject = { null };
for (IExportConfig export : sourceDepImplComp.config().exports()) {
if (str2libProject[0] != null) {
break;
}
export.accept(new IExportVisitor() {
@Override
public void visit(LangDirExport resource) {
}
@Override
public void visit(LangFileExport resource) {
if (resource.language.equals("StrategoLang") && resource.file.endsWith("str2lib")) {
str2libProject[0] = resource.file;
}
}
@Override
public void visit(ResourceExport resource) {
}
});
}
if (str2libProject[0] != null) {
final String str2IncludeDir = "str2-includes/" + sourceDepImplComp.id().toFullFileString() + "-" + sourceDepImplComp.sequenceId();
final ResourcePath str2LibFile = new FSPath(resourceService.localFileUpdate(sourceDepImplComp.location().resolveFile(str2libProject[0]), paths.replicateDir().resolveFile(str2IncludeDir)));
@Nullable final DynamicClassLoadingFacet facet = sourceDepImplComp.facet(DynamicClassLoadingFacet.class);
if (facet == null) {
continue;
}
final ArrayList<ResourcePath> jarFiles = new ArrayList<>(facet.jarFiles.size());
for (FileObject file : facet.jarFiles) {
jarFiles.add(new FSPath(resourceService.localFileUpdate(file, paths.replicateDir().resolveFile(str2IncludeDir))));
}
str2libraries.add(new ValueSupplier<>(new Stratego2LibInfo(str2LibFile, jarFiles)));
}
}
}
final ArrayList<STask<?>> sdfTasks = new ArrayList<>(0);
// Gather all Stratego files to be checked for changes
final Set<Path> changedFiles = GenerateSourcesBuilder.getChangedFiles(projectLocation);
final Set<ResourceKey> changedResources = new HashSet<>(changedFiles.size() * 2);
for (Path changedFile : changedFiles) {
changedResources.add(new FSPath(changedFile));
}
final ArrayList<IModuleImportService.ModuleIdentifier> linkedLibraries = new ArrayList<>();
GenerateSourcesBuilder.splitOffLinkedLibrariesIncludeDirs(extraArgs, linkedLibraries, strjIncludeDirs, projectLocation.getPath());
final LastModified<IStrategoTerm> astWLM = new LastModified<>(ast, Instant.now().getEpochSecond());
final boolean isLibrary = false;
final ModuleIdentifier moduleIdentifier = new ModuleIdentifier(strFile.getName().endsWith(".str"), isLibrary, moduleName, new FSPath(strFile));
final ModuleIdentifier mainModuleIdentifier = new ModuleIdentifier(strMainFile.getName().endsWith(".str"), isLibrary, strMainModule, new FSPath(strMainFile));
final boolean autoImportStd = false;
final IModuleImportService.ImportResolutionInfo importResolutionInfo = new IModuleImportService.ImportResolutionInfo(sdfTasks, strjIncludeDirs, linkedLibraries, str2libraries);
final CheckModuleInput checkModuleInput = new CheckModuleInput(new FrontInput.FileOpenInEditor(moduleIdentifier, importResolutionInfo, astWLM, autoImportStd), mainModuleIdentifier, projectPath);
final Task<CheckOpenModuleOutput> checkModuleTask = checkModuleProvider.get().createTask(checkModuleInput);
final IPieProvider pieProvider = pieProviderProvider.get();
final Pie pie = pieProvider.pie();
final IStrategoList.Builder errors = B.listBuilder();
final IStrategoList.Builder warnings = B.listBuilder();
final IStrategoList.Builder notes = B.listBuilder();
final CheckOpenModuleOutput analysisInformation;
// noinspection SynchronizationOnLocalVariableOrMethodParameter
synchronized (pie) {
GenerateSourcesBuilder.initCompiler(pieProvider, checkModuleTask);
try (final MixedSession session = pie.newSession()) {
TopDownSession tdSession = session.updateAffectedBy(changedResources);
session.deleteUnobservedTasks(t -> true, (t, r) -> {
if (Objects.equals(r.getLeafExtension(), "java")) {
logger.debug("Deleting garbage from previous build: " + r);
return true;
}
return false;
});
analysisInformation = tdSession.getOutput(checkModuleTask);
} catch (ExecException e) {
logger.warn("Incremental Stratego build failed", e);
return null;
} catch (InterruptedException e) {
// Ignore
return null;
}
}
for (Message message : analysisInformation.messages) {
final IStrategoString term = factory.makeString(message.locationTermString);
if (message.filename == null) {
logger.debug("No origins for message: " + message);
} else {
// otherwise filename would have also been null
assert message.sourceRegion != null;
if (!resourceService.resolve(message.filename).equals(resourceService.resolve(baseLoc, path))) {
continue;
}
final ImploderAttachment imploderAttachment = ImploderAttachment.createCompactPositionAttachment(message.filename, message.sourceRegion.startRow, message.sourceRegion.startColumn, message.sourceRegion.startOffset, message.sourceRegion.endOffset);
term.putAttachment(imploderAttachment);
}
final IStrategoTuple messageTuple = B.tuple(term, B.string(message.getMessage()));
switch(message.severity) {
case ERROR:
errors.add(messageTuple);
break;
case NOTE:
notes.add(messageTuple);
break;
case WARNING:
warnings.add(messageTuple);
break;
}
}
return B.tuple(analysisInformation.astWithCasts, B.list(errors), B.list(warnings), B.list(notes));
}
Aggregations