Search in sources :

Example 1 with IMessageInfo

use of mb.nabl2.constraints.messages.IMessageInfo in project spoofax by metaborg.

the class AbstractConstraintAnalyzer method message.

private IMessage message(ITerm originatingTerm, IMessageInfo messageInfo, MessageSeverity severity, IUnifier unifier, C context, FileObject defaultLocation) {
    Optional<TermOrigin> maybeOrigin = TermOrigin.get(originatingTerm);
    if (maybeOrigin.isPresent()) {
        TermOrigin origin = maybeOrigin.get();
        ISourceRegion region = JSGLRSourceRegionFactory.fromTokens(origin.getLeftToken(), origin.getRightToken());
        FileObject resource = resourceService.resolve(context.location(), origin.getResource());
        String message = messageInfo.getContent().apply(unifier::findRecursive).toString(prettyprint(context, resource(resource, context)));
        return MessageFactory.newAnalysisMessage(resource, region, message, severity, null);
    } else {
        String message = messageInfo.getContent().apply(unifier::findRecursive).toString(prettyprint(context, null));
        return MessageFactory.newAnalysisMessageAtTop(defaultLocation, message, severity, null);
    }
}
Also used : ISourceRegion(org.metaborg.core.source.ISourceRegion) FileObject(org.apache.commons.vfs2.FileObject) TermOrigin(mb.nabl2.stratego.TermOrigin)

Example 2 with IMessageInfo

use of mb.nabl2.constraints.messages.IMessageInfo in project spoofax by metaborg.

the class ConstraintMultiFileAnalyzer method analyzeSemiIncremental.

private ISpoofaxAnalyzeResults analyzeSemiIncremental(Map<String, ISpoofaxParseUnit> changed, java.util.Set<String> removed, IMultiFileScopeGraphContext context, HybridInterpreter runtime, String strategy, IProgress progress, ICancel cancel) throws AnalysisException {
    final NaBL2DebugConfig debugConfig = context.config().debug();
    final Timer totalTimer = new Timer(true);
    final AggregateTimer collectionTimer = new AggregateTimer();
    final AggregateTimer solverTimer = new AggregateTimer();
    final AggregateTimer finalizeTimer = new AggregateTimer();
    final String globalSource = "";
    final Function1<String, String> globalFresh = base -> context.unit(globalSource).fresh().fresh(base);
    for (String input : removed) {
        context.removeUnit(input);
    }
    final int n = changed.size();
    final int w = context.units().size() / 2;
    progress.setWorkRemaining(n + w + 1);
    if (debugConfig.analysis() || debugConfig.files()) {
        logger.info("Analyzing {} files in {}.", n, context.location());
    }
    final Collection<ISpoofaxAnalyzeUnit> results = Lists.newArrayList();
    final Collection<ISpoofaxAnalyzeUnitUpdate> updateResults = Lists.newArrayList();
    try {
        // initial
        InitialResult initialResult;
        final Optional<ITerm> customInitial;
        {
            if (debugConfig.collection()) {
                logger.info("Collecting initial constraints.");
            }
            if (context.initialResult().isPresent()) {
                initialResult = context.initialResult().get();
                customInitial = context.initialResult().flatMap(r -> r.getCustomResult());
            } else {
                collectionTimer.start();
                try {
                    final ITerm globalAST = Actions.sourceTerm(globalSource, B.EMPTY_TUPLE);
                    ITerm initialResultTerm = doAction(strategy, Actions.analyzeInitial(globalSource, globalAST), context, runtime).orElseThrow(() -> new AnalysisException(context, "No initial result."));
                    initialResult = InitialResult.matcher().match(initialResultTerm).orElseThrow(() -> new AnalysisException(context, "Invalid initial results."));
                    customInitial = doCustomAction(strategy, Actions.customInitial(globalSource, globalAST), context, runtime);
                    initialResult = initialResult.withCustomResult(customInitial);
                    context.setInitialResult(initialResult);
                } finally {
                    collectionTimer.stop();
                }
            }
            if (debugConfig.collection()) {
                logger.info("Initial constraints collected.");
            }
        }
        // global parameters, that form the interface for a single unit
        final java.util.Set<ITermVar> intfVars = Sets.newHashSet();
        {
            initialResult.getArgs().getParams().stream().forEach(param -> intfVars.addAll(param.getVars()));
            initialResult.getArgs().getType().ifPresent(type -> intfVars.addAll(type.getVars()));
        }
        final SemiIncrementalMultiFileSolver solver = new SemiIncrementalMultiFileSolver(context.config().debug(), callExternal(runtime));
        // global
        ISolution initialSolution;
        {
            if (context.initialSolution().isPresent()) {
                initialSolution = context.initialSolution().get();
            } else {
                try {
                    solverTimer.start();
                    final IProgress subprogress = progress.subProgress(1);
                    GraphSolution preSolution = solver.solveGraph(ImmutableBaseSolution.of(initialResult.getConfig(), initialResult.getConstraints(), PersistentUnifier.Immutable.of()), globalFresh, cancel, subprogress);
                    preSolution = solver.reportUnsolvedGraphConstraints(preSolution);
                    initialSolution = solver.solveIntra(preSolution, intfVars, null, globalFresh, cancel, subprogress);
                    if (debugConfig.resolution()) {
                        logger.info("Reduced file constraints to {}.", initialSolution.constraints().size());
                    }
                } catch (SolverException e) {
                    throw new AnalysisException(context, e);
                } finally {
                    solverTimer.stop();
                }
                context.setInitialSolution(initialSolution);
            }
        }
        final java.util.Set<Scope> intfScopes = Sets.newHashSet();
        {
            initialResult.getArgs().getParams().stream().forEach(param -> Scope.matcher().match(param, initialSolution.unifier()).ifPresent(intfScopes::add));
        }
        // units
        final Map<String, IStrategoTerm> astsByFile = Maps.newHashMap();
        final Map<String, IMessage> failures = Maps.newHashMap();
        final Multimap<String, IMessage> ambiguitiesByFile = HashMultimap.create();
        for (Map.Entry<String, ISpoofaxParseUnit> input : changed.entrySet()) {
            final String source = input.getKey();
            final ISpoofaxParseUnit parseUnit = input.getValue();
            final ITerm ast = strategoTerms.fromStratego(parseUnit.ast());
            if (debugConfig.files()) {
                logger.info("Analyzing {}.", source);
            }
            final IMultiFileScopeGraphUnit unit = context.unit(source);
            unit.clear();
            try {
                UnitResult unitResult;
                final Optional<ITerm> customUnit;
                {
                    if (debugConfig.collection()) {
                        logger.info("Collecting constraints of {}.", source);
                    }
                    try {
                        collectionTimer.start();
                        final ITerm unitResultTerm = doAction(strategy, Actions.analyzeUnit(source, ast, initialResult.getArgs()), context, runtime).orElseThrow(() -> new AnalysisException(context, "No unit result."));
                        unitResult = UnitResult.matcher().match(unitResultTerm).orElseThrow(() -> new MetaborgException("Invalid unit results."));
                        final ITerm desugaredAST = unitResult.getAST();
                        customUnit = doCustomAction(strategy, Actions.customUnit(source, desugaredAST, customInitial.orElse(B.EMPTY_TUPLE)), context, runtime);
                        unitResult = unitResult.withCustomResult(customUnit);
                        final IStrategoTerm analyzedAST = strategoTerms.toStratego(desugaredAST);
                        astsByFile.put(source, analyzedAST);
                        ambiguitiesByFile.putAll(source, analysisCommon.ambiguityMessages(parseUnit.source(), parseUnit.ast()));
                        unit.setUnitResult(unitResult);
                    } finally {
                        collectionTimer.stop();
                    }
                    if (debugConfig.collection()) {
                        logger.info("Collected {} constraints of {}.", unitResult.getConstraints().size(), source);
                    }
                }
                {
                    final ISolution unitSolution;
                    if (debugConfig.resolution()) {
                        logger.info("Reducing {} constraints of {}.", unitResult.getConstraints().size(), source);
                    }
                    try {
                        solverTimer.start();
                        final Function1<String, String> fresh = base -> context.unit(source).fresh().fresh(base);
                        final IProgress subprogress = progress.subProgress(1);
                        GraphSolution preSolution = solver.solveGraph(ImmutableBaseSolution.of(initialResult.getConfig(), unitResult.getConstraints(), initialSolution.unifier()), fresh, cancel, subprogress);
                        preSolution = solver.reportUnsolvedGraphConstraints(preSolution);
                        unitSolution = solver.solveIntra(preSolution, intfVars, intfScopes, fresh, cancel, subprogress);
                        if (debugConfig.resolution()) {
                            logger.info("Reduced file constraints to {}.", unitSolution.constraints().size());
                        }
                    } catch (SolverException e) {
                        throw new AnalysisException(context, e);
                    } finally {
                        solverTimer.stop();
                    }
                    unit.setPartialSolution(unitSolution);
                    if (debugConfig.files() || debugConfig.resolution()) {
                        logger.info("Analyzed {}: {} errors, {} warnings, {} notes, {} unsolved constraints.", source, unitSolution.messages().getErrors().size(), unitSolution.messages().getWarnings().size(), unitSolution.messages().getNotes().size(), unitSolution.constraints().size());
                    }
                }
            } catch (MetaborgException e) {
                logger.warn("Analysis of " + source + " failed.", e);
                failures.put(source, MessageFactory.newAnalysisErrorAtTop(parseUnit.source(), "File analysis failed.", e));
            }
        }
        // solve
        final ISolution solution;
        final List<Optional<ITerm>> customUnits = Lists.newArrayList();
        {
            final List<ISolution> partialSolutions = Lists.newArrayList();
            for (IMultiFileScopeGraphUnit unit : context.units()) {
                unit.partialSolution().ifPresent(partialSolutions::add);
                unit.unitResult().map(UnitResult::getCustomResult).ifPresent(customUnits::add);
            }
            if (debugConfig.resolution()) {
                logger.info("Solving {} partial solutions.", partialSolutions.size());
            }
            ISolution sol;
            try {
                solverTimer.start();
                Function1<String, String> fresh = base -> context.unit(globalSource).fresh().fresh(base);
                IMessageInfo message = ImmutableMessageInfo.of(MessageKind.ERROR, MessageContent.of(), Actions.sourceTerm(globalSource));
                sol = solver.solveInter(initialSolution, partialSolutions, message, fresh, cancel, progress.subProgress(w));
                sol = solver.reportUnsolvedConstraints(sol);
            } catch (SolverException e) {
                throw new AnalysisException(context, e);
            } finally {
                solverTimer.stop();
            }
            if (!sol.flowSpecSolution().controlFlowGraph().isEmpty()) {
                logger.debug("CFG is not empty: calling FlowSpec dataflow solver");
                sol = new FixedPoint().entryPoint(sol, getFlowSpecTransferFunctions(context.language()));
            }
            solution = sol;
            context.setSolution(solution);
            if (debugConfig.resolution()) {
                logger.info("Project constraints solved.");
            }
        }
        // final
        FinalResult finalResult;
        final Optional<ITerm> customFinal;
        final Optional<CustomSolution> customSolution;
        {
            if (debugConfig.analysis()) {
                logger.info("Finalizing project analysis.");
            }
            finalizeTimer.start();
            try {
                ITerm finalResultTerm = doAction(strategy, Actions.analyzeFinal(globalSource), context, runtime).orElseThrow(() -> new AnalysisException(context, "No final result."));
                finalResult = FinalResult.matcher().match(finalResultTerm, solution.unifier()).orElseThrow(() -> new AnalysisException(context, "Invalid final results."));
                customFinal = doCustomAction(strategy, Actions.customFinal(globalSource, customInitial.orElse(B.EMPTY_TUPLE), Optionals.filter(customUnits)), context, runtime);
                finalResult = finalResult.withCustomResult(customFinal);
                context.setFinalResult(finalResult);
                customSolution = customFinal.flatMap(cs -> CustomSolution.matcher().match(cs, solution.unifier()));
                customSolution.ifPresent(cs -> context.setCustomSolution(cs));
            } finally {
                finalizeTimer.stop();
            }
            if (debugConfig.analysis()) {
                logger.info("Project analysis finalized.");
            }
        }
        // errors
        {
            if (debugConfig.analysis()) {
                logger.info("Processing project messages.");
            }
            Messages.Transient messageBuilder = Messages.Transient.of();
            messageBuilder.addAll(Messages.unsolvedErrors(solution.constraints()));
            messageBuilder.addAll(solution.messages().getAll());
            customSolution.map(CustomSolution::getMessages).map(IMessages::getAll).ifPresent(messageBuilder::addAll);
            IMessages messages = messageBuilder.freeze();
            IRelation3.Transient<String, MessageSeverity, IMessage> messagesByFile = HashTrieRelation3.Transient.of();
            messagesByFile(failures.values(), messagesByFile, context);
            messagesByFile(messages(messages.getAll(), solution.unifier(), context, context.location()), messagesByFile, context);
            // precondition: the messagesByFile should not contain any files that do not have corresponding units
            for (IMultiFileScopeGraphUnit unit : context.units()) {
                final String source = unit.resource();
                final java.util.Set<IMessage> fileMessages = messagesByFile.get(source).stream().map(Map.Entry::getValue).collect(Collectors2.toHashSet());
                if (changed.containsKey(source)) {
                    fileMessages.addAll(ambiguitiesByFile.get(source));
                    final boolean valid = !failures.containsKey(source);
                    final boolean success = valid && messagesByFile.get(source, MessageSeverity.ERROR).isEmpty();
                    final IStrategoTerm analyzedAST = astsByFile.get(source);
                    results.add(unitService.analyzeUnit(changed.get(source), new AnalyzeContrib(valid, success, analyzedAST != null, analyzedAST, fileMessages, -1), context));
                } else {
                    try {
                        final FileObject file = context.location().resolveFile(source);
                        updateResults.add(unitService.analyzeUnitUpdate(file, new AnalyzeUpdateData(fileMessages), context));
                    } catch (IOException ex) {
                        logger.error("Could not resolve {} to update messages", source);
                    }
                }
                messagesByFile.remove(source);
            }
            if (!messagesByFile.keySet().isEmpty()) {
                logger.error("Found messages for unanalyzed files {}", messagesByFile.keySet());
            }
            if (debugConfig.analysis() || debugConfig.files() || debugConfig.resolution()) {
                logger.info("Analyzed {} files: {} errors, {} warnings, {} notes.", n, messages.getErrors().size(), messages.getWarnings().size(), messages.getNotes().size());
            }
        }
    } catch (InterruptedException e) {
        logger.debug("Analysis was interrupted.");
    } finally {
        totalTimer.stop();
    }
    final ConstraintDebugData debugData = new ConstraintDebugData(totalTimer.stop(), collectionTimer.total(), solverTimer.total(), finalizeTimer.total());
    if (debugConfig.analysis()) {
        logger.info("{}", debugData);
    }
    return new SpoofaxAnalyzeResults(results, updateResults, context, debugData);
}
Also used : UnitResult(mb.nabl2.spoofax.analysis.UnitResult) ITerm(mb.nabl2.terms.ITerm) ISpoofaxAnalyzeUnit(org.metaborg.spoofax.core.unit.ISpoofaxAnalyzeUnit) IProgress(org.metaborg.util.task.IProgress) Inject(com.google.inject.Inject) IRelation3(mb.nabl2.util.collections.IRelation3) MetaborgException(org.metaborg.core.MetaborgException) HashMultimap(com.google.common.collect.HashMultimap) ICancel(org.metaborg.util.task.ICancel) Map(java.util.Map) ITermVar(mb.nabl2.terms.ITermVar) SolverException(mb.nabl2.solver.SolverException) ISolution(mb.nabl2.solver.ISolution) IStrategoTerm(org.spoofax.interpreter.terms.IStrategoTerm) B(mb.nabl2.terms.build.TermBuild.B) GraphSolution(mb.nabl2.solver.solvers.BaseSolver.GraphSolution) ISpoofaxAnalyzer(org.metaborg.spoofax.core.analysis.ISpoofaxAnalyzer) ISpoofaxParseUnit(org.metaborg.spoofax.core.unit.ISpoofaxParseUnit) Collection(java.util.Collection) ISpoofaxTracingService(org.metaborg.spoofax.core.tracing.ISpoofaxTracingService) IMessageInfo(mb.nabl2.constraints.messages.IMessageInfo) SemiIncrementalMultiFileSolver(mb.nabl2.solver.solvers.SemiIncrementalMultiFileSolver) AnalyzeUpdateData(org.metaborg.spoofax.core.unit.AnalyzeUpdateData) Sets(com.google.common.collect.Sets) FinalResult(mb.nabl2.spoofax.analysis.FinalResult) List(java.util.List) Optionals(org.metaborg.util.optionals.Optionals) Optional(java.util.Optional) LoggerUtils(org.metaborg.util.log.LoggerUtils) Timer(org.metaborg.util.time.Timer) ImmutableBaseSolution(mb.nabl2.solver.solvers.ImmutableBaseSolution) IMultiFileScopeGraphContext(org.metaborg.spoofax.core.context.scopegraph.IMultiFileScopeGraphContext) ITermFactoryService(org.metaborg.spoofax.core.terms.ITermFactoryService) AggregateTimer(org.metaborg.util.time.AggregateTimer) Function1(org.metaborg.util.functions.Function1) AnalysisCommon(org.metaborg.spoofax.core.analysis.AnalysisCommon) ISpoofaxAnalyzeResults(org.metaborg.spoofax.core.analysis.ISpoofaxAnalyzeResults) Multimap(com.google.common.collect.Multimap) Actions(mb.nabl2.spoofax.analysis.Actions) Lists(com.google.common.collect.Lists) ISpoofaxAnalyzeUnitUpdate(org.metaborg.spoofax.core.unit.ISpoofaxAnalyzeUnitUpdate) IMultiFileScopeGraphUnit(org.metaborg.spoofax.core.context.scopegraph.IMultiFileScopeGraphUnit) ISpoofaxUnitService(org.metaborg.spoofax.core.unit.ISpoofaxUnitService) HybridInterpreter(org.strategoxt.HybridInterpreter) PersistentUnifier(mb.nabl2.terms.unification.PersistentUnifier) ILogger(org.metaborg.util.log.ILogger) ImmutableMessageInfo(mb.nabl2.constraints.messages.ImmutableMessageInfo) HashTrieRelation3(mb.nabl2.util.collections.HashTrieRelation3) Messages(mb.nabl2.solver.messages.Messages) IOException(java.io.IOException) MessageKind(mb.nabl2.constraints.messages.MessageKind) Scope(mb.nabl2.scopegraph.terms.Scope) CustomSolution(mb.nabl2.spoofax.analysis.CustomSolution) IMessage(org.metaborg.core.messages.IMessage) FileObject(org.apache.commons.vfs2.FileObject) Maps(com.google.common.collect.Maps) NaBL2DebugConfig(mb.nabl2.config.NaBL2DebugConfig) MessageContent(mb.nabl2.constraints.messages.MessageContent) AnalyzeContrib(org.metaborg.spoofax.core.unit.AnalyzeContrib) IMessages(mb.nabl2.solver.messages.IMessages) SpoofaxAnalyzeResults(org.metaborg.spoofax.core.analysis.SpoofaxAnalyzeResults) Collectors2(org.metaborg.util.stream.Collectors2) FixedPoint(mb.flowspec.runtime.solver.FixedPoint) IResourceService(org.metaborg.core.resource.IResourceService) IStrategoCommon(org.metaborg.spoofax.core.stratego.IStrategoCommon) InitialResult(mb.nabl2.spoofax.analysis.InitialResult) MessageSeverity(org.metaborg.core.messages.MessageSeverity) AnalysisException(org.metaborg.core.analysis.AnalysisException) IStrategoRuntimeService(org.metaborg.spoofax.core.stratego.IStrategoRuntimeService) MessageFactory(org.metaborg.core.messages.MessageFactory) ISpoofaxAnalyzeResults(org.metaborg.spoofax.core.analysis.ISpoofaxAnalyzeResults) SpoofaxAnalyzeResults(org.metaborg.spoofax.core.analysis.SpoofaxAnalyzeResults) ITermVar(mb.nabl2.terms.ITermVar) GraphSolution(mb.nabl2.solver.solvers.BaseSolver.GraphSolution) List(java.util.List) FileObject(org.apache.commons.vfs2.FileObject) InitialResult(mb.nabl2.spoofax.analysis.InitialResult) IProgress(org.metaborg.util.task.IProgress) Optional(java.util.Optional) AnalyzeUpdateData(org.metaborg.spoofax.core.unit.AnalyzeUpdateData) FinalResult(mb.nabl2.spoofax.analysis.FinalResult) IMessage(org.metaborg.core.messages.IMessage) Function1(org.metaborg.util.functions.Function1) ISolution(mb.nabl2.solver.ISolution) IMultiFileScopeGraphUnit(org.metaborg.spoofax.core.context.scopegraph.IMultiFileScopeGraphUnit) CustomSolution(mb.nabl2.spoofax.analysis.CustomSolution) NaBL2DebugConfig(mb.nabl2.config.NaBL2DebugConfig) Map(java.util.Map) IStrategoTerm(org.spoofax.interpreter.terms.IStrategoTerm) ISpoofaxAnalyzeUnitUpdate(org.metaborg.spoofax.core.unit.ISpoofaxAnalyzeUnitUpdate) SemiIncrementalMultiFileSolver(mb.nabl2.solver.solvers.SemiIncrementalMultiFileSolver) MetaborgException(org.metaborg.core.MetaborgException) UnitResult(mb.nabl2.spoofax.analysis.UnitResult) AggregateTimer(org.metaborg.util.time.AggregateTimer) IMessageInfo(mb.nabl2.constraints.messages.IMessageInfo) AnalyzeContrib(org.metaborg.spoofax.core.unit.AnalyzeContrib) FixedPoint(mb.flowspec.runtime.solver.FixedPoint) ISpoofaxAnalyzeUnit(org.metaborg.spoofax.core.unit.ISpoofaxAnalyzeUnit) ISpoofaxParseUnit(org.metaborg.spoofax.core.unit.ISpoofaxParseUnit) IMessages(mb.nabl2.solver.messages.IMessages) IOException(java.io.IOException) FixedPoint(mb.flowspec.runtime.solver.FixedPoint) Timer(org.metaborg.util.time.Timer) AggregateTimer(org.metaborg.util.time.AggregateTimer) Scope(mb.nabl2.scopegraph.terms.Scope) AnalysisException(org.metaborg.core.analysis.AnalysisException) ITerm(mb.nabl2.terms.ITerm) SolverException(mb.nabl2.solver.SolverException)

Example 3 with IMessageInfo

use of mb.nabl2.constraints.messages.IMessageInfo in project nabl by metaborg.

the class EqualityComponent method solve.

private Optional<SolveResult> solve(CInequal constraint) {
    ITerm left = constraint.getLeft();
    ITerm right = constraint.getRight();
    if (unifier().areEqual(left, right)) {
        MessageContent content = MessageContent.builder().append(constraint.getLeft().toString()).append(" and ").append(constraint.getRight().toString()).append(" must be inequal, but are not.").build();
        IMessageInfo message = constraint.getMessageInfo().withDefaultContent(content);
        return Optional.of(SolveResult.messages(message));
    } else {
        return unifier().areUnequal(left, right) ? Optional.of(SolveResult.empty()) : Optional.empty();
    }
}
Also used : MessageContent(mb.nabl2.constraints.messages.MessageContent) ITerm(mb.nabl2.terms.ITerm) IMessageInfo(mb.nabl2.constraints.messages.IMessageInfo)

Example 4 with IMessageInfo

use of mb.nabl2.constraints.messages.IMessageInfo in project nabl by metaborg.

the class SetComponent method solve.

private Optional<SolveResult> solve(CDistinct constraint) {
    ITerm setTerm = unifier().findRecursive(constraint.getSet());
    if (!setTerm.isGround()) {
        return Optional.empty();
    }
    Optional<Set<IElement<ITerm>>> maybeSet = evaluator.match(setTerm, unifier());
    if (!(maybeSet.isPresent())) {
        return Optional.empty();
    }
    Multimap<Object, IElement<ITerm>> proj = SetEvaluator.project(maybeSet.get(), constraint.getProjection());
    List<IElement<ITerm>> duplicates = Lists.newArrayList();
    for (Object key : proj.keySet()) {
        Collection<IElement<ITerm>> values = proj.get(key);
        if (values.size() > 1) {
            duplicates.addAll(values);
        }
    }
    if (duplicates.isEmpty()) {
        return Optional.of(SolveResult.empty());
    } else {
        MessageContent content = MessageContent.builder().append(B.newAppl(NAME_OP)).append(" has duplicates in ").append(setTerm).build();
        Iterable<IMessageInfo> messages = makeMessages(constraint.getMessageInfo().withDefaultContent(content), duplicates);
        return Optional.of(SolveResult.messages(messages));
    }
}
Also used : MessageContent(mb.nabl2.constraints.messages.MessageContent) IElement(mb.nabl2.sets.IElement) CEvalSet(mb.nabl2.constraints.sets.CEvalSet) Set(java.util.Set) ITerm(mb.nabl2.terms.ITerm) IMessageInfo(mb.nabl2.constraints.messages.IMessageInfo)

Example 5 with IMessageInfo

use of mb.nabl2.constraints.messages.IMessageInfo in project nabl by metaborg.

the class NameResolutionComponent method solve.

// ------------------------------------------------------------------------------------------------------//
private Optional<SolveResult> solve(CResolve r) {
    final ITerm refTerm = unifier().findRecursive(r.getReference());
    if (!refTerm.isGround()) {
        return Optional.empty();
    }
    final Occurrence ref = Occurrence.matcher().match(refTerm, unifier()).orElseThrow(() -> new TypeException("Expected an occurrence as first argument to " + r));
    final Optional<java.util.Set<IResolutionPath<Scope, Label, Occurrence>>> maybePathsAndDeps = nameResolution.resolve(ref);
    if (!maybePathsAndDeps.isPresent()) {
        return Optional.empty();
    }
    final java.util.Set<IResolutionPath<Scope, Label, Occurrence>> paths = maybePathsAndDeps.get();
    final List<Occurrence> declarations = Paths.resolutionPathsToDecls(paths);
    final Multimap<String, String> deps = HashMultimap.create();
    deps.putAll(ref.getIndex().getResource(), declarations.stream().map(d -> d.getIndex().getResource()).collect(Collectors.toSet()));
    final SolveResult result;
    switch(declarations.size()) {
        case 0:
            {
                IMessageInfo message = r.getMessageInfo().withDefaultContent(MessageContent.builder().append(ref).append(" does not resolve.").build());
                result = SolveResult.messages(message);
                break;
            }
        case 1:
            {
                final Occurrence decl = declarations.get(0);
                result = SolveResult.constraints(ImmutableCEqual.of(r.getDeclaration(), decl, r.getMessageInfo()));
                break;
            }
        default:
            {
                IMessageInfo message = r.getMessageInfo().withDefaultContent(MessageContent.builder().append("Resolution of ").append(ref).append(" is ambiguous.").build());
                result = SolveResult.messages(message);
                break;
            }
    }
    return Optional.of(ImmutableSolveResult.copyOf(result).withDependencies(deps));
}
Also used : IResolutionPath(mb.nabl2.scopegraph.path.IResolutionPath) Label(mb.nabl2.scopegraph.terms.Label) TypeException(mb.nabl2.solver.TypeException) IMessageInfo(mb.nabl2.constraints.messages.IMessageInfo) SolveResult(mb.nabl2.solver.ISolver.SolveResult) ImmutableSolveResult(mb.nabl2.solver.ImmutableSolveResult) Scope(mb.nabl2.scopegraph.terms.Scope) ITerm(mb.nabl2.terms.ITerm) Occurrence(mb.nabl2.scopegraph.terms.Occurrence)

Aggregations

IMessageInfo (mb.nabl2.constraints.messages.IMessageInfo)10 ITerm (mb.nabl2.terms.ITerm)10 MessageContent (mb.nabl2.constraints.messages.MessageContent)7 SolveResult (mb.nabl2.solver.ISolver.SolveResult)6 Optional (java.util.Optional)4 Map (java.util.Map)3 Set (java.util.Set)3 CEvalSet (mb.nabl2.constraints.sets.CEvalSet)3 Scope (mb.nabl2.scopegraph.terms.Scope)3 IElement (mb.nabl2.sets.IElement)3 SolverCore (mb.nabl2.solver.SolverCore)3 HashMultimap (com.google.common.collect.HashMultimap)2 Lists (com.google.common.collect.Lists)2 Maps (com.google.common.collect.Maps)2 Multimap (com.google.common.collect.Multimap)2 Sets (com.google.common.collect.Sets)2 Collection (java.util.Collection)2 List (java.util.List)2 NaBL2DebugConfig (mb.nabl2.config.NaBL2DebugConfig)2 ImmutableCEqual (mb.nabl2.constraints.equality.ImmutableCEqual)2