use of org.metaborg.core.resource.ResourceChange in project spoofax by metaborg.
the class DialectProcessor method update.
@Override
public void update(FileObject location, Iterable<ResourceChange> changes) {
final int numChanges = Iterables.size(changes);
if (numChanges == 0) {
return;
}
final ILanguage strategoLanguage = languageService.getLanguage(SpoofaxConstants.LANG_STRATEGO_NAME);
if (strategoLanguage == null) {
logger.debug("Could not find Stratego language, Stratego dialects cannot be updated");
return;
}
final ILanguageImpl strategoImpl = strategoLanguage.activeImpl();
if (strategoImpl == null) {
logger.debug("Could not find active Stratego language implementation, " + "Stratego dialects cannot be updated");
return;
}
logger.debug("Processing dialect updates for {}", location);
// HACK: assuming single syntax facet
final SyntaxFacet baseFacet = strategoImpl.facet(SyntaxFacet.class);
if (baseFacet == null) {
logger.debug("Active Stratego language implementation has no syntax facet, " + "Stratego dialects cannot be updated");
return;
}
for (ResourceChange change : changes) {
final FileObject resource = change.resource;
try {
if (!FileSelectorUtils.include(selector, resource, location)) {
continue;
}
} catch (FileSystemException e) {
continue;
}
final String fileName = FilenameUtils.getBaseName(resource.getName().getBaseName());
final SyntaxFacet newFacet = new SyntaxFacet(resource, baseFacet.completionParseTable, baseFacet.startSymbols, baseFacet.singleLineCommentPrefixes, baseFacet.multiLineCommentCharacters, baseFacet.fenceCharacters);
final ResourceChangeKind changeKind = change.kind;
try {
switch(changeKind) {
case Create:
add(fileName, resource, strategoImpl, newFacet);
break;
case Delete:
remove(fileName, resource);
break;
case Modify:
update(fileName, resource, newFacet);
break;
case Rename:
if (change.from != null) {
remove(fileName, resource);
}
if (change.to != null) {
add(fileName, resource, strategoImpl, newFacet);
}
break;
case Copy:
if (change.to != null) {
add(fileName, resource, strategoImpl, newFacet);
}
break;
default:
logger.error("Unhandled resource change kind {}", changeKind);
break;
}
} catch (MetaborgRuntimeException e) {
logger.error("Failed to update dialect", e);
}
}
}
use of org.metaborg.core.resource.ResourceChange in project spoofax by metaborg.
the class Builder method identifyResources.
private void identifyResources(Iterable<ResourceChange> changes, BuildInput input, Multimap<ILanguageImpl, IdentifiedResourceChange> identifiedChanges, ICancel cancel) throws InterruptedException {
final Iterable<ILanguageImpl> languages = input.buildOrder.languages();
final FileSelector selector = input.selector;
final FileObject location = input.project.location();
for (ResourceChange change : changes) {
cancel.throwIfCancelled();
final FileObject resource = change.resource;
if (selector != null) {
try {
if (!FileSelectorUtils.include(selector, resource, location)) {
continue;
}
} catch (FileSystemException e) {
logger.error("Error determining if {} should be ignored from the build, including it", e, resource);
}
}
final IdentifiedResource identifiedResource = languageIdentifier.identifyToResource(resource, languages);
if (identifiedResource != null) {
final IdentifiedResourceChange identifiedChange = new IdentifiedResourceChange(change, identifiedResource);
identifiedChanges.put(identifiedChange.language, identifiedChange);
}
}
}
use of org.metaborg.core.resource.ResourceChange in project spoofax by metaborg.
the class FilesBuildState method includeDiff.
private Iterable<IdentifiedResourceChange> includeDiff(LanguageBuildState newState, Iterable<IdentifiedResource> newFiles) {
final Collection<IdentifiedResourceChange> changes = Lists.newLinkedList();
final Set<FileName> existingFiles = Sets.newHashSet(include.files);
for (IdentifiedResource identifiedResource : newFiles) {
final FileObject resource = identifiedResource.resource;
final FileName name = resource.getName();
final long newModification = newState.include.add(resource);
existingFiles.remove(name);
if (include.files.contains(name)) {
final long existingModification = include.modification.get(name);
if (existingModification != newModification) {
changes.add(new IdentifiedResourceChange(new ResourceChange(resource, ResourceChangeKind.Modify), identifiedResource));
}
} else {
changes.add(new IdentifiedResourceChange(new ResourceChange(resource, ResourceChangeKind.Create), identifiedResource));
}
}
for (FileName name : existingFiles) {
newState.include.remove(name);
final FileObject resource = resourceService.resolve(name.getURI());
final IdentifiedResource identifiedResource = languageIdentifierService.identifyToResource(resource, Iterables2.singleton(language));
if (identifiedResource != null) {
changes.add(new IdentifiedResourceChange(new ResourceChange(resource, ResourceChangeKind.Delete), identifiedResource));
}
}
return changes;
}
use of org.metaborg.core.resource.ResourceChange in project spoofax by metaborg.
the class Builder method build.
@Override
public IBuildOutput<P, A, AU, T> build(BuildInput input, IProgress progress, ICancel cancel) throws InterruptedException {
cancel.throwIfCancelled();
final Multimap<ILanguageImpl, IdentifiedResourceChange> changes = ArrayListMultimap.create();
identifyResources(input.sourceChanges, input, changes, cancel);
if (changes.size() == 0) {
// When there are no source changes, keep the old state and skip building.
final IBuildOutputInternal<P, A, AU, T> buildOutput = buildOutputProvider.get();
buildOutput.setState(input.state);
return buildOutput;
}
cancel.throwIfCancelled();
logger.info("Building " + input.project.location());
final BuildState newState = new BuildState();
final IBuildOutputInternal<P, A, AU, T> buildOutput = buildOutputProvider.get();
buildOutput.setState(newState);
final Iterable<ILanguageImpl> buildOrder = input.buildOrder.buildOrder();
progress.setWorkRemaining(Iterables.size(buildOrder));
for (ILanguageImpl language : buildOrder) {
cancel.throwIfCancelled();
final LanguageBuildState languageState = input.state.get(resourceService, languageIdentifier, language);
final Collection<IdentifiedResourceChange> sourceChanges = changes.get(language);
if (sourceChanges.size() == 0) {
// When there are no source changes for this language, keep the old state and don't build.
newState.add(language, languageState);
continue;
}
final Iterable<FileObject> includePaths = input.includePaths.get(language);
final Iterable<IdentifiedResource> includeFiles = languagePathService.toFiles(includePaths, language);
final LanguageBuildDiff diff = languageState.diff(changes.get(language), includeFiles);
final boolean pardoned = input.pardonedLanguages.contains(language);
final Collection<FileObject> newResources = updateLanguageResources(input, language, diff, buildOutput, pardoned, progress.subProgress(1), cancel);
final Iterable<ResourceChange> newResourceChanges = ResourceUtils.toChanges(newResources, ResourceChangeKind.Create);
identifyResources(newResourceChanges, input, changes, cancel);
newState.add(language, diff.newState);
}
final IMessagePrinter printer = input.messagePrinter;
if (printer != null) {
printer.printSummary();
}
return buildOutput;
}
use of org.metaborg.core.resource.ResourceChange in project spoofax by metaborg.
the class Builder method parse.
private Collection<P> parse(BuildInput input, ILanguageImpl langImpl, Iterable<IdentifiedResourceChange> changes, boolean pardoned, Collection<FileObject> changedResources, Set<FileName> removedResources, Collection<IMessage> extraMessages, RefBool success, IProgress progress, ICancel cancel) throws InterruptedException {
final int size = Iterables.size(changes);
progress.setWorkRemaining(size);
final Collection<P> allParseUnits = Lists.newArrayListWithCapacity(size);
if (size == 0) {
return allParseUnits;
}
progress.setDescription("Parsing " + size + " file(s) of " + langImpl.belongsTo().name());
logger.debug("Parsing {} resources", size);
for (IdentifiedResourceChange identifiedChange : changes) {
cancel.throwIfCancelled();
final ResourceChange change = identifiedChange.change;
final FileObject resource = change.resource;
final ILanguageImpl dialect = identifiedChange.dialect;
final ResourceChangeKind changeKind = change.kind;
try {
if (changeKind == ResourceChangeKind.Delete) {
parseResultUpdater.remove(resource);
removedResources.add(resource.getName());
// LEGACY: add empty parse result, to indicate to analysis that this resource was
// removed. There is special handling in updating the analysis result processor, the marker
// updater, and the compiler, to exclude removed resources.
final I inputUnit = unitService.emptyInputUnit(resource, langImpl, dialect);
final P emptyParseResult = unitService.emptyParseUnit(inputUnit);
allParseUnits.add(emptyParseResult);
// Don't add resource as changed when it has been deleted, because it does not exist any more.
progress.work(1);
} else {
final String sourceText = sourceTextService.text(resource);
parseResultUpdater.invalidate(resource);
final I inputUnit = unitService.inputUnit(resource, sourceText, langImpl, dialect);
final P parseResult = syntaxService.parse(inputUnit, progress.subProgress(1), cancel);
final boolean noErrors = printMessages(parseResult.messages(), "Parsing", input, pardoned);
success.and(noErrors);
allParseUnits.add(parseResult);
parseResultUpdater.update(resource, parseResult);
changedResources.add(resource);
}
} catch (ParseException e) {
final String message = logger.format("Parsing {} failed unexpectedly", resource);
final boolean noErrors = printMessage(resource, message, e, input, pardoned);
success.and(noErrors);
parseResultUpdater.error(resource, e);
extraMessages.add(MessageFactory.newParseErrorAtTop(resource, "Parsing failed unexpectedly", e));
changedResources.add(resource);
} catch (IOException e) {
final String message = logger.format("Getting source text for {} failed unexpectedly", resource);
final boolean noErrors = printMessage(resource, message, e, input, pardoned);
success.and(noErrors);
final I inputUnit = unitService.emptyInputUnit(resource, langImpl, dialect);
parseResultUpdater.error(resource, new ParseException(inputUnit, e));
extraMessages.add(MessageFactory.newParseErrorAtTop(resource, "Getting source text failed unexpectedly", e));
changedResources.add(resource);
}
}
return allParseUnits;
}
Aggregations