Search in sources :

Example 1 with ResourceChange

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);
        }
    }
}
Also used : ILanguage(org.metaborg.core.language.ILanguage) MetaborgRuntimeException(org.metaborg.core.MetaborgRuntimeException) SyntaxFacet(org.metaborg.spoofax.core.syntax.SyntaxFacet) FileSystemException(org.apache.commons.vfs2.FileSystemException) ILanguageImpl(org.metaborg.core.language.ILanguageImpl) ResourceChangeKind(org.metaborg.core.resource.ResourceChangeKind) FileObject(org.apache.commons.vfs2.FileObject) ResourceChange(org.metaborg.core.resource.ResourceChange)

Example 2 with ResourceChange

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);
        }
    }
}
Also used : FileSystemException(org.apache.commons.vfs2.FileSystemException) ILanguageImpl(org.metaborg.core.language.ILanguageImpl) FileSelector(org.apache.commons.vfs2.FileSelector) LanguagesFileSelector(org.metaborg.core.language.LanguagesFileSelector) FileObject(org.apache.commons.vfs2.FileObject) ResourceChange(org.metaborg.core.resource.ResourceChange) IdentifiedResourceChange(org.metaborg.core.resource.IdentifiedResourceChange) IdentifiedResource(org.metaborg.core.language.IdentifiedResource) IdentifiedResourceChange(org.metaborg.core.resource.IdentifiedResourceChange)

Example 3 with ResourceChange

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;
}
Also used : FileName(org.apache.commons.vfs2.FileName) FileObject(org.apache.commons.vfs2.FileObject) IdentifiedResourceChange(org.metaborg.core.resource.IdentifiedResourceChange) IdentifiedResource(org.metaborg.core.language.IdentifiedResource) IdentifiedResourceChange(org.metaborg.core.resource.IdentifiedResourceChange) ResourceChange(org.metaborg.core.resource.ResourceChange)

Example 4 with ResourceChange

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;
}
Also used : IdentifiedResourceChange(org.metaborg.core.resource.IdentifiedResourceChange) ILanguageImpl(org.metaborg.core.language.ILanguageImpl) IMessagePrinter(org.metaborg.core.messages.IMessagePrinter) FileObject(org.apache.commons.vfs2.FileObject) IdentifiedResource(org.metaborg.core.language.IdentifiedResource) ResourceChange(org.metaborg.core.resource.ResourceChange) IdentifiedResourceChange(org.metaborg.core.resource.IdentifiedResourceChange)

Example 5 with ResourceChange

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;
}
Also used : IOException(java.io.IOException) IdentifiedResourceChange(org.metaborg.core.resource.IdentifiedResourceChange) ILanguageImpl(org.metaborg.core.language.ILanguageImpl) ResourceChangeKind(org.metaborg.core.resource.ResourceChangeKind) FileObject(org.apache.commons.vfs2.FileObject) ParseException(org.metaborg.core.syntax.ParseException) ResourceChange(org.metaborg.core.resource.ResourceChange) IdentifiedResourceChange(org.metaborg.core.resource.IdentifiedResourceChange)

Aggregations

FileObject (org.apache.commons.vfs2.FileObject)6 ResourceChange (org.metaborg.core.resource.ResourceChange)6 IdentifiedResourceChange (org.metaborg.core.resource.IdentifiedResourceChange)5 ILanguageImpl (org.metaborg.core.language.ILanguageImpl)4 IdentifiedResource (org.metaborg.core.language.IdentifiedResource)3 FileSystemException (org.apache.commons.vfs2.FileSystemException)2 ResourceChangeKind (org.metaborg.core.resource.ResourceChangeKind)2 IOException (java.io.IOException)1 FileName (org.apache.commons.vfs2.FileName)1 FileSelector (org.apache.commons.vfs2.FileSelector)1 MetaborgRuntimeException (org.metaborg.core.MetaborgRuntimeException)1 ILanguage (org.metaborg.core.language.ILanguage)1 LanguagesFileSelector (org.metaborg.core.language.LanguagesFileSelector)1 IMessagePrinter (org.metaborg.core.messages.IMessagePrinter)1 ParseException (org.metaborg.core.syntax.ParseException)1 SyntaxFacet (org.metaborg.spoofax.core.syntax.SyntaxFacet)1