Search in sources :

Example 6 with IContext

use of org.metaborg.core.context.IContext in project spoofax by metaborg.

the class Builder method transform.

private Collection<T> transform(BuildInput input, ILanguageImpl langImpl, FileObject location, Multimap<IContext, A> allAnalysisUnits, Set<FileName> includeFiles, boolean pardoned, Set<FileName> removedResources, Collection<IMessage> extraMessages, RefBool success, IProgress progress, ICancel cancel) throws InterruptedException {
    final int size = allAnalysisUnits.size();
    progress.setWorkRemaining(size);
    final Collection<T> allTransformUnits = Lists.newArrayListWithCapacity(size);
    if (size == 0) {
        return allTransformUnits;
    }
    progress.setDescription("Compiling " + size + " file(s) of " + langImpl.belongsTo().name());
    logger.debug("Compiling {} analysis results", size);
    for (Entry<IContext, Collection<A>> entry : allAnalysisUnits.asMap().entrySet()) {
        cancel.throwIfCancelled();
        final IContext context = entry.getKey();
        final Iterable<A> analysisResults = entry.getValue();
        try (IClosableLock lock = context.read()) {
            for (A analysisResult : analysisResults) {
                cancel.throwIfCancelled();
                final FileObject source = analysisResult.source();
                final FileName name = source.getName();
                if (removedResources.contains(name) || includeFiles.contains(name)) {
                    // Don't compile removed resources, which the analysis results contain for legacy reasons.
                    // Don't transform included resources, they should just be parsed and analyzed.
                    progress.work(1);
                    continue;
                }
                if (!analysisResult.valid()) {
                    logger.warn("Input result for {} is invalid, cannot transform it", source != null ? source.getName().getPath() : "detached source");
                    progress.work(1);
                    continue;
                }
                for (ITransformGoal goal : input.transformGoals) {
                    cancel.throwIfCancelled();
                    if (!transformService.available(context, goal)) {
                        logger.trace("No {} transformation required for {}", goal, context.language());
                        progress.work(1);
                        continue;
                    }
                    try {
                        final Collection<TA> results = transformService.transform(analysisResult, context, goal);
                        for (TA result : results) {
                            final boolean noErrors = printMessages(result.messages(), goal + " transformation", input, pardoned);
                            success.and(noErrors);
                            @SuppressWarnings("unchecked") final T genericResult = (T) result;
                            allTransformUnits.add(genericResult);
                        }
                        progress.work(1);
                    } catch (TransformException e) {
                        final String message = String.format("Transformation failed unexpectedly for %s", name);
                        logger.error(message, e);
                        final boolean noErrors = printMessage(source, message, e, input, pardoned);
                        success.and(noErrors);
                        extraMessages.add(MessageFactory.newBuilderErrorAtTop(location, "Transformation failed unexpectedly", e));
                    }
                }
            }
        // GTODO: also compile any affected sources
        }
    }
    return allTransformUnits;
}
Also used : IContext(org.metaborg.core.context.IContext) FileName(org.apache.commons.vfs2.FileName) TransformException(org.metaborg.core.transform.TransformException) ITransformGoal(org.metaborg.core.action.ITransformGoal) Collection(java.util.Collection) IClosableLock(org.metaborg.util.concurrent.IClosableLock) FileObject(org.apache.commons.vfs2.FileObject)

Example 7 with IContext

use of org.metaborg.core.context.IContext 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 8 with IContext

use of org.metaborg.core.context.IContext in project spoofax by metaborg.

the class OutlineService method outline.

@Override
public IOutline outline(ISpoofaxAnalyzeUnit result) throws MetaborgException {
    if (!result.valid() || !result.hasAst()) {
        return null;
    }
    final FileObject source = result.source();
    final IContext context = result.context();
    final ILanguageImpl language = context.language();
    final FacetContribution<OutlineFacet> facetContrib = facet(language);
    final OutlineFacet facet = facetContrib.facet;
    final ILanguageComponent contributor = facetContrib.contributor;
    final String strategy = facet.strategyName;
    try {
        final HybridInterpreter interpreter = strategoRuntimeService.runtime(contributor, context, true);
        final IStrategoTerm input = common.builderInputTerm(result.ast(), source, context.location());
        final IStrategoTerm outlineTerm = common.invoke(interpreter, input, strategy);
        if (outlineTerm == null) {
            return null;
        }
        final IOutline outline = toOutline(outlineTerm, facet.expandTo, contributor.location());
        return outline;
    } catch (MetaborgException e) {
        throw new MetaborgException("Creating outline failed", e);
    }
}
Also used : IContext(org.metaborg.core.context.IContext) IStrategoTerm(org.spoofax.interpreter.terms.IStrategoTerm) ILanguageImpl(org.metaborg.core.language.ILanguageImpl) IOutline(org.metaborg.core.outline.IOutline) MetaborgException(org.metaborg.core.MetaborgException) HybridInterpreter(org.strategoxt.HybridInterpreter) FileObject(org.apache.commons.vfs2.FileObject) IStrategoString(org.spoofax.interpreter.terms.IStrategoString) ILanguageComponent(org.metaborg.core.language.ILanguageComponent)

Example 9 with IContext

use of org.metaborg.core.context.IContext in project spoofax by metaborg.

the class OutlineService method outline.

@Override
public IOutline outline(ISpoofaxParseUnit result) throws MetaborgException {
    if (!result.valid()) {
        return null;
    }
    final FileObject source = result.source();
    final IProject project = projectService.get(source);
    final ILanguageImpl langImpl = result.input().langImpl();
    @Nullable IContext context;
    if (project == null) {
        context = null;
    } else {
        try {
            context = contextService.get(source, project, langImpl);
        } catch (ContextException | MetaborgRuntimeException e) {
            // Failed to get a context, ignore and use the source file to get a stratego runtime later.
            context = null;
        }
    }
    final FacetContribution<OutlineFacet> facetContrib = facet(langImpl);
    final OutlineFacet facet = facetContrib.facet;
    final ILanguageComponent contributor = facetContrib.contributor;
    final String strategy = facet.strategyName;
    try {
        final HybridInterpreter interpreter;
        if (context == null) {
            interpreter = strategoRuntimeService.runtime(contributor, source, true);
        } else {
            interpreter = strategoRuntimeService.runtime(contributor, context, true);
        }
        final IStrategoTerm input = common.builderInputTerm(result.ast(), source, source);
        final IStrategoTerm outlineTerm = common.invoke(interpreter, input, strategy);
        if (outlineTerm == null) {
            return null;
        }
        final IOutline outline = toOutline(outlineTerm, facet.expandTo, contributor.location());
        return outline;
    } catch (MetaborgException e) {
        throw new MetaborgException("Creating outline failed", e);
    }
}
Also used : MetaborgRuntimeException(org.metaborg.core.MetaborgRuntimeException) IContext(org.metaborg.core.context.IContext) IStrategoTerm(org.spoofax.interpreter.terms.IStrategoTerm) IOutline(org.metaborg.core.outline.IOutline) MetaborgException(org.metaborg.core.MetaborgException) HybridInterpreter(org.strategoxt.HybridInterpreter) IStrategoString(org.spoofax.interpreter.terms.IStrategoString) IProject(org.metaborg.core.project.IProject) ContextException(org.metaborg.core.context.ContextException) ILanguageImpl(org.metaborg.core.language.ILanguageImpl) FileObject(org.apache.commons.vfs2.FileObject) ILanguageComponent(org.metaborg.core.language.ILanguageComponent) Nullable(javax.annotation.Nullable)

Example 10 with IContext

use of org.metaborg.core.context.IContext in project spoofax by metaborg.

the class Builder method analyze.

private Multimap<IContext, A> analyze(BuildInput input, ILanguageImpl langImpl, FileObject location, Multimap<IContext, P> sourceParseUnits, Iterable<P> includeParseUnits, boolean pardoned, Collection<AU> analyzeUpdates, Set<FileName> removedResources, Collection<IMessage> extraMessages, RefBool success, IProgress progress, ICancel cancel) throws InterruptedException {
    final int size = sourceParseUnits.size() + Iterables.size(includeParseUnits);
    final Multimap<IContext, A> allAnalyzeUnits = ArrayListMultimap.create();
    if (size == 0) {
        return allAnalyzeUnits;
    }
    final Set<Entry<IContext, Collection<P>>> toAnalyze = sourceParseUnits.asMap().entrySet();
    final int toAnalyzeSize = toAnalyze.size();
    progress.setWorkRemaining(toAnalyzeSize);
    progress.setDescription("Analyzing " + size + " file(s) of " + langImpl.belongsTo().name());
    logger.debug("Analyzing {} parse results in {} context(s)", size, toAnalyzeSize);
    for (Entry<IContext, Collection<P>> entry : toAnalyze) {
        cancel.throwIfCancelled();
        final IContext context = entry.getKey();
        final Iterable<P> parseResults = Iterables.concat(entry.getValue(), includeParseUnits);
        try {
            try (IClosableLock lock = context.write()) {
                analysisResultUpdater.invalidate(parseResults);
                final IAnalyzeResults<A, AU> results = analysisService.analyzeAll(parseResults, context, progress.subProgress(1), cancel);
                for (A result : results.results()) {
                    cancel.throwIfCancelled();
                    final boolean noErrors = printMessages(result.messages(), "Analysis", input, pardoned);
                    success.and(noErrors);
                    analysisResultUpdater.update(result, removedResources);
                    allAnalyzeUnits.put(context, result);
                }
                analyzeUpdates.addAll(results.updates());
            } finally {
                context.persist();
            }
        } catch (AnalysisException e) {
            final String message = "Analysis failed unexpectedly";
            final boolean noErrors = printMessage(message, e, input, pardoned);
            success.and(noErrors);
            analysisResultUpdater.error(parseResults, e);
            extraMessages.add(MessageFactory.newAnalysisErrorAtTop(location, message, e));
        } catch (IOException e) {
            final String message = "Persisting analysis data failed unexpectedly";
            final boolean noErrors = printMessage(message, e, input, pardoned);
            success.and(noErrors);
            extraMessages.add(MessageFactory.newAnalysisErrorAtTop(location, message, e));
        }
    }
    return allAnalyzeUnits;
}
Also used : IContext(org.metaborg.core.context.IContext) IOException(java.io.IOException) Entry(java.util.Map.Entry) AnalysisException(org.metaborg.core.analysis.AnalysisException) Collection(java.util.Collection) IClosableLock(org.metaborg.util.concurrent.IClosableLock)

Aggregations

IContext (org.metaborg.core.context.IContext)13 FileObject (org.apache.commons.vfs2.FileObject)10 ILanguageImpl (org.metaborg.core.language.ILanguageImpl)10 MetaborgException (org.metaborg.core.MetaborgException)9 IStrategoTerm (org.spoofax.interpreter.terms.IStrategoTerm)7 IProject (org.metaborg.core.project.IProject)6 HybridInterpreter (org.strategoxt.HybridInterpreter)6 ILanguageComponent (org.metaborg.core.language.ILanguageComponent)5 Nullable (javax.annotation.Nullable)4 MetaborgRuntimeException (org.metaborg.core.MetaborgRuntimeException)4 ContextException (org.metaborg.core.context.ContextException)4 ISourceRegion (org.metaborg.core.source.ISourceRegion)4 SourceRegion (org.metaborg.core.source.SourceRegion)4 TermWithRegion (org.metaborg.spoofax.core.tracing.TracingCommon.TermWithRegion)4 IClosableLock (org.metaborg.util.concurrent.IClosableLock)4 ITermFactory (org.spoofax.interpreter.terms.ITermFactory)4 IStrategoString (org.spoofax.interpreter.terms.IStrategoString)3 IOException (java.io.IOException)2 Collection (java.util.Collection)2 FileName (org.apache.commons.vfs2.FileName)2