use of org.metaborg.core.syntax.ParseException in project spoofax by metaborg.
the class ParseResultProcessor method getUpdates.
private BehaviorSubject<ParseChange<P>> getUpdates(I unit) {
final FileObject resource = unit.source();
final FileName name = resource.getName();
// THREADING: it is possible that two different threads asking for a subject may do the parsing twice here, as
// this is not an atomic operation. However, the chance is very low and it does not break anything (only
// duplicates some work), so it is acceptable.
BehaviorSubject<ParseChange<P>> updates = updatesPerResource.get(name);
if (updates == null) {
updates = BehaviorSubject.create();
updatesPerResource.put(name, updates);
try {
logger.trace("Parsing for {}", resource);
final P result = syntaxService.parse(unit);
updates.onNext(ParseChange.update(result));
} catch (ParseException e) {
final String message = String.format("Parsing for %s failed", name);
logger.error(message, e);
updates.onNext(ParseChange.<P>error(e));
}
}
return updates;
}
use of org.metaborg.core.syntax.ParseException in project spoofax by metaborg.
the class ParseResultProcessor method request.
@Override
public Observable<P> request(final I input) {
final FileObject resource = input.source();
return Observable.create(new OnSubscribe<P>() {
@Override
public void call(Subscriber<? super P> observer) {
if (observer.isUnsubscribed()) {
logger.trace("Unsubscribed from parse result request for {}", input);
return;
}
final BehaviorSubject<ParseChange<P>> updates = getUpdates(input);
final ParseChange<P> update = updates.toBlocking().first(new Func1<ParseChange<P>, Boolean>() {
@Override
public Boolean call(ParseChange<P> updateToFilter) {
final UpdateKind kind = updateToFilter.kind;
return kind != UpdateKind.Invalidate;
}
});
if (observer.isUnsubscribed()) {
logger.trace("Unsubscribed from parse result request for {}", resource);
return;
}
switch(update.kind) {
case Update:
logger.trace("Returning cached parse result for {}", resource);
observer.onNext(update.unit);
observer.onCompleted();
break;
case Error:
logger.trace("Returning parse error for {}", resource);
observer.onError(update.exception);
break;
case Remove:
{
final String message = logger.format("Parse result for {} was removed unexpectedly", resource);
logger.error(message);
observer.onError(new ParseException(input, message));
break;
}
default:
{
final String message = logger.format("Unexpected parse update kind {} for {}", update.kind, resource);
logger.error(message);
observer.onError(new ParseException(input, message));
break;
}
}
}
});
}
use of org.metaborg.core.syntax.ParseException in project spoofax by metaborg.
the class Sdf2ParenthesizeStamper method stampOf.
@Override
public Stamp stampOf(File file) {
if (!FileCommands.exists(file)) {
return new ValueStamp<>(this, null);
}
final IStrategoTerm term;
try {
term = context.parse(file);
} catch (ParseException | IOException e) {
return LastModifiedStamper.instance.stampOf(file);
}
if (term == null) {
return LastModifiedStamper.instance.stampOf(file);
}
final ParenExtractor parenExtractor = new ParenExtractor(context.termFactory());
parenExtractor.visit(term);
return new ValueStamp<>(this, Pair.create(parenExtractor.getRelevantProds(), parenExtractor.getPriorities()));
}
use of org.metaborg.core.syntax.ParseException 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;
}
use of org.metaborg.core.syntax.ParseException in project spoofax by metaborg.
the class LegacyParseFilePrimitive method call.
@Override
public boolean call(IContext env, Strategy[] strategies, IStrategoTerm[] terms) throws InterpreterException {
if (!Tools.isTermString(terms[0]))
return false;
if (!Tools.isTermString(terms[3]))
return false;
try {
final String pathOrInput = Tools.asJavaString(terms[0]);
final String pathOrInput2 = Tools.asJavaString(terms[3]);
FileObject resource;
String text;
try {
resource = resourceService.resolve(pathOrInput);
if (!resource.exists() || resource.getType() != FileType.FILE) {
resource = resourceService.resolve(pathOrInput2);
text = pathOrInput;
} else {
text = sourceTextService.text(resource);
}
} catch (MetaborgRuntimeException | IOException e) {
resource = resourceService.resolve(pathOrInput2);
text = pathOrInput;
}
if (resource.getType() != FileType.FILE) {
return false;
}
final IdentifiedResource identifiedResource = languageIdentifierService.identifyToResource(resource);
if (identifiedResource == null) {
return false;
}
final ISpoofaxInputUnit input = unitService.inputUnit(resource, text, identifiedResource.language, identifiedResource.dialect);
final ISpoofaxParseUnit result = syntaxService.parse(input);
if (result.valid() && result.success()) {
env.setCurrent(result.ast());
} else {
return false;
}
} catch (ParseException | IOException e) {
throw new InterpreterException("Parsing failed unexpectedly", e);
}
return true;
}
Aggregations