use of mb.stratego.build.strincr.Stratego2LibInfo in project spoofax by metaborg.
the class LanguageSpecBuilder method generateSourcesBuilderInput.
private GenerateSourcesBuilder.Input generateSourcesBuilderInput(LanguageSpecBuildInput input) throws FileSystemException, MetaborgException {
final ISpoofaxLanguageSpec languageSpec = input.languageSpec();
final ISpoofaxLanguageSpecConfig config = languageSpec.config();
final FileObject baseLoc = input.languageSpec().location();
final SpoofaxLangSpecCommonPaths paths = new SpoofaxLangSpecCommonPaths(baseLoc);
final FileObject buildInfoLoc = paths.plutoBuildInfoDir();
final SpoofaxContext context = new SpoofaxContext(baseLoc, buildInfoLoc);
// Sort source dependencies to ensure deterministic input.
final ArrayList<LanguageIdentifier> sourceDeps = new ArrayList<>(config.sourceDeps());
Collections.sort(sourceDeps);
// SDF
final Boolean sdfEnabled = config.sdfEnabled();
final String sdfModule = config.sdfName();
final JSGLRVersion jsglrVersion = config.jsglrVersion();
final Boolean checkOverlap = config.checkOverlap();
final Boolean checkPriorities = config.checkPriorities();
final FileObject sdfFileCandidate;
final SdfVersion sdfVersion = config.sdfVersion();
final Sdf2tableVersion sdf2tableVersion = config.sdf2tableVersion();
switch(sdfVersion) {
case sdf2:
final Iterable<FileObject> sdfRoots = languagePathService.sourcePaths(input.project(), SpoofaxConstants.LANG_SDF_NAME);
sdfFileCandidate = paths.findSyntaxMainFile(sdfRoots, sdfModule);
break;
case sdf3:
sdfFileCandidate = paths.syntaxSrcGenMainFile(sdfModule);
break;
default:
throw new MetaborgException("Unknown SDF version: " + sdfVersion);
}
@Nullable final File sdfFile;
if (sdfFileCandidate != null && sdfFileCandidate.exists()) {
sdfFile = resourceService.localPath(sdfFileCandidate);
} else {
sdfFile = null;
}
@Nullable final File sdfExternalDef;
final String sdfExternalDefStr = config.sdfExternalDef();
if (sdfExternalDefStr != null) {
final FileObject sdfExternalDefLoc = resourceService.resolve(sdfExternalDefStr);
if (!sdfExternalDefLoc.exists()) {
throw new MetaborgException("External SDF definition at " + sdfExternalDefLoc + " does not exist");
}
sdfExternalDef = resourceService.localFile(sdfExternalDefLoc);
} else {
sdfExternalDef = null;
}
final Iterable<FileObject> sdfIncludePaths = languagePathService.sourceAndIncludePaths(languageSpec, SpoofaxConstants.LANG_SDF_NAME);
final FileObject packSdfIncludesReplicateDir = paths.replicateDir().resolveFile("pack-sdf-includes");
packSdfIncludesReplicateDir.delete(new AllFileSelector());
final List<File> packSdfIncludePaths = Lists.newArrayList();
for (FileObject path : sdfIncludePaths) {
if (!path.exists()) {
continue;
}
packSdfIncludePaths.add(resourceService.localFileUpdate(path, packSdfIncludesReplicateDir));
}
final Arguments packSdfArgs = config.sdfArgs();
// SDF completions
final String sdfCompletionModule = config.sdfName() + "-completion-insertions";
@Nullable final File sdfCompletionFile;
FileObject sdfCompletionFileCandidate = null;
if (!sdf2tableVersion.javaBased) {
sdfCompletionFileCandidate = paths.syntaxCompletionMainFile(sdfCompletionModule);
} else {
sdfCompletionFileCandidate = paths.syntaxCompletionMainFileNormalized(sdfCompletionModule);
}
if (sdfCompletionFileCandidate != null && sdfCompletionFileCandidate.exists()) {
sdfCompletionFile = resourceService.localPath(sdfCompletionFileCandidate);
} else {
sdfCompletionFile = null;
}
// Meta-SDF
final Iterable<FileObject> sdfRoots = languagePathService.sourcePaths(input.project(), SpoofaxConstants.LANG_SDF_NAME);
// final String sdfMetaModule = config.metaSdfName();
List<String> sdfMetaModules = config.sdfMetaFiles();
@Nullable final List<File> sdfMetaFiles = Lists.newArrayList();
for (String sdfMetaModule : sdfMetaModules) {
final FileObject sdfMetaFileCandidate;
if (config.sdf2tableVersion().javaBased)
sdfMetaFileCandidate = paths.syntaxSrcGenMainNormFile(sdfMetaModule);
else
sdfMetaFileCandidate = paths.findSyntaxMainFile(sdfRoots, sdfMetaModule);
if (sdfMetaFileCandidate != null && sdfMetaFileCandidate.exists())
sdfMetaFiles.add(resourceService.localPath(sdfMetaFileCandidate));
}
// Stratego
final Boolean strEnabled = config.strEnabled();
final String strModule = config.strategoName();
final ArrayList<Supplier<Stratego2LibInfo>> str2libraries = new ArrayList<>();
for (LanguageIdentifier sourceDep : sourceDeps) {
@Nullable final ILanguageImpl sourceDepImpl = languageService.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 Iterable<FileObject> strRoots = languagePathService.sourcePaths(input.project(), SpoofaxConstants.LANG_STRATEGO_NAME);
final FileObject strFileCandidate = config.strVersion().findStrMainFile(paths, strRoots, strModule);
@Nullable final File strFile;
if (strEnabled) {
if (strFileCandidate != null && strFileCandidate.exists()) {
strFile = resourceService.localPath(strFileCandidate);
} else {
final String fileExtension = config.strVersion() == StrategoVersion.v1 ? "str" : "str2";
throw new MetaborgException("Cannot find Stratego main file '" + NameUtil.toJavaId(strModule.toLowerCase()) + "." + fileExtension + "'.");
}
} else {
strFile = null;
}
final String strStratPkg = paths.strJavaTransPkg(config.identifier().id);
final String strJavaStratPkg = paths.strJavaStratPkg(config.identifier().id);
final FileObject strJavaStratFileCandidate = paths.strMainJavaStratFile(config.identifier().id);
@Nullable final File strJavaStratFile;
if (strJavaStratFileCandidate.exists()) {
strJavaStratFile = resourceService.localPath(strJavaStratFileCandidate);
} else {
strJavaStratFile = null;
}
final StrategoFormat strFormat = config.strFormat();
@Nullable final File strExternalJar;
final String strExternalJarStr = config.strExternalJar();
if (strEnabled && strExternalJarStr != null) {
final FileObject strExternalJarLoc = resourceService.resolve(strExternalJarStr);
if (!strExternalJarLoc.exists()) {
throw new MetaborgException("External Stratego JAR at " + strExternalJarLoc + " does not exist");
}
strExternalJar = resourceService.localFile(strExternalJarLoc);
} else {
strExternalJar = null;
}
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");
strjIncludesReplicateDir.delete(new AllFileSelector());
final List<File> strjIncludeDirs = Lists.newArrayList();
final List<File> strjIncludeFiles = Lists.newArrayList();
for (FileObject path : strIncludePaths) {
if (!path.exists()) {
continue;
}
if (path.isFolder()) {
strjIncludeDirs.add(resourceService.localFileUpdate(path, strjIncludesReplicateDir));
}
if (path.isFile()) {
strjIncludeFiles.add(resourceService.localFileUpdate(path, strjIncludesReplicateDir));
}
}
final Arguments strjArgs = config.strArgs();
return new GenerateSourcesBuilder.Input(context, config.identifier(), sourceDeps, sdfEnabled, sdfModule, sdfFile, jsglrVersion, sdfVersion, sdf2tableVersion, checkOverlap, checkPriorities, sdfExternalDef, packSdfIncludePaths, packSdfArgs, sdfCompletionModule, sdfCompletionFile, sdfMetaModules, sdfMetaFiles, strEnabled, strFile, strStratPkg, strJavaStratPkg, strJavaStratFile, strFormat, strExternalJar, strExternalJarFlags, strjIncludeDirs, strjIncludeFiles, str2libraries, strjArgs, languageSpec.config().strShadowJar(), languageSpec.config().strVersion());
}
use of mb.stratego.build.strincr.Stratego2LibInfo 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