Search in sources :

Example 1 with IdentifiedResourceChange

use of org.metaborg.core.resource.IdentifiedResourceChange 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 2 with IdentifiedResourceChange

use of org.metaborg.core.resource.IdentifiedResourceChange in project spoofax by metaborg.

the class Builder method updateLanguageResources.

private Collection<FileObject> updateLanguageResources(BuildInput input, ILanguageImpl language, LanguageBuildDiff diff, IBuildOutputInternal<P, A, AU, T> output, boolean pardoned, IProgress progress, ICancel cancel) throws InterruptedException {
    cancel.throwIfCancelled();
    final boolean analyze = input.analyze && analysisService.available(language);
    final boolean transform = input.transform;
    progress.setWorkRemaining(10 + (analyze ? 45 : 0) + (transform ? 45 : 0));
    final Iterable<IdentifiedResourceChange> sourceChanges = diff.sourceChanges;
    final Iterable<IdentifiedResourceChange> includeChanges = diff.includeChanges;
    final Set<FileName> includes = Sets.newHashSet();
    for (IdentifiedResourceChange includeChange : includeChanges) {
        includes.add(includeChange.change.resource.getName());
    }
    final FileObject location = input.project.location();
    final Collection<FileObject> changedSources = Sets.newHashSet();
    final Set<FileName> removedResources = Sets.newHashSet();
    final Collection<IMessage> extraMessages = Lists.newLinkedList();
    final RefBool success = new RefBool(true);
    logger.info("Building {} sources, {} includes of {}", Iterables.size(sourceChanges), Iterables.size(includeChanges), language);
    // Parse
    cancel.throwIfCancelled();
    final Collection<P> sourceParseUnits = parse(input, language, sourceChanges, pardoned, changedSources, removedResources, extraMessages, success, progress.subProgress(5), cancel);
    // GTODO: when a new context is created, all include files need to be parsed and analyzed in that context, this
    // approach does not do that!
    final Collection<P> includeParseUnits = parse(input, language, includeChanges, pardoned, changedSources, removedResources, extraMessages, success, progress.subProgress(5), cancel);
    final Iterable<P> allParseResults = Iterables.concat(sourceParseUnits, includeParseUnits);
    // Analyze
    cancel.throwIfCancelled();
    final Multimap<IContext, A> allAnalyzeUnits;
    final Collection<AU> allAnalyzeUpdates = Lists.newArrayList();
    if (analyze) {
        // Segregate by context
        final Multimap<IContext, P> parseUnitsPerContext = ArrayListMultimap.create();
        for (P parseResult : sourceParseUnits) {
            cancel.throwIfCancelled();
            final FileObject resource = parseResult.source();
            final ILanguageImpl langImpl = parseResult.input().langImpl();
            try {
                if (contextService.available(langImpl)) {
                    final IContext context = contextService.get(resource, input.project, langImpl);
                    parseUnitsPerContext.put(context, parseResult);
                }
            } catch (ContextException e) {
                final String message = String.format("Failed to retrieve context for parse result of %s", resource);
                printMessage(resource, message, e, input, pardoned);
                extraMessages.add(MessageFactory.newAnalysisErrorAtTop(resource, "Failed to retrieve context", e));
            }
        }
        // Run analysis
        cancel.throwIfCancelled();
        allAnalyzeUnits = analyze(input, language, location, parseUnitsPerContext, includeParseUnits, pardoned, allAnalyzeUpdates, removedResources, extraMessages, success, progress.subProgress(45), cancel);
    } else {
        allAnalyzeUnits = ArrayListMultimap.create();
    }
    // Transform
    cancel.throwIfCancelled();
    final Collection<T> allTransformUnits;
    if (transform) {
        allTransformUnits = transform(input, language, location, allAnalyzeUnits, includes, pardoned, removedResources, extraMessages, success, progress.subProgress(45), cancel);
    } else {
        allTransformUnits = Lists.newLinkedList();
    }
    printMessages(extraMessages, "Something", input, pardoned);
    output.add(success.get(), removedResources, includes, changedSources, allParseResults, allAnalyzeUnits.values(), allAnalyzeUpdates, allTransformUnits, extraMessages);
    final Collection<FileObject> newResources = Lists.newArrayList();
    for (T transformUnit : allTransformUnits) {
        for (ITransformOutput transformOutput : transformUnit.outputs()) {
            final FileObject outputFile = transformOutput.output();
            if (outputFile != null) {
                newResources.add(outputFile);
            }
        }
    }
    return newResources;
}
Also used : ITransformOutput(org.metaborg.core.transform.ITransformOutput) IContext(org.metaborg.core.context.IContext) FileName(org.apache.commons.vfs2.FileName) IdentifiedResourceChange(org.metaborg.core.resource.IdentifiedResourceChange) ContextException(org.metaborg.core.context.ContextException) FileObject(org.apache.commons.vfs2.FileObject) IMessage(org.metaborg.core.messages.IMessage) RefBool(org.metaborg.util.RefBool) ILanguageImpl(org.metaborg.core.language.ILanguageImpl)

Example 3 with IdentifiedResourceChange

use of org.metaborg.core.resource.IdentifiedResourceChange 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 IdentifiedResourceChange

use of org.metaborg.core.resource.IdentifiedResourceChange 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 IdentifiedResourceChange

use of org.metaborg.core.resource.IdentifiedResourceChange 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 IdentifiedResourceChange (org.metaborg.core.resource.IdentifiedResourceChange)6 ResourceChange (org.metaborg.core.resource.ResourceChange)5 ILanguageImpl (org.metaborg.core.language.ILanguageImpl)4 IdentifiedResource (org.metaborg.core.language.IdentifiedResource)3 FileName (org.apache.commons.vfs2.FileName)2 IOException (java.io.IOException)1 FileSelector (org.apache.commons.vfs2.FileSelector)1 FileSystemException (org.apache.commons.vfs2.FileSystemException)1 ContextException (org.metaborg.core.context.ContextException)1 IContext (org.metaborg.core.context.IContext)1 LanguagesFileSelector (org.metaborg.core.language.LanguagesFileSelector)1 IMessage (org.metaborg.core.messages.IMessage)1 IMessagePrinter (org.metaborg.core.messages.IMessagePrinter)1 ResourceChangeKind (org.metaborg.core.resource.ResourceChangeKind)1 ParseException (org.metaborg.core.syntax.ParseException)1 ITransformOutput (org.metaborg.core.transform.ITransformOutput)1 RefBool (org.metaborg.util.RefBool)1