Search in sources :

Example 1 with IdentifiedDialect

use of org.metaborg.core.language.dialect.IdentifiedDialect in project spoofax by metaborg.

the class DialectIdentifier method identify.

@Override
public IdentifiedDialect identify(FileObject resource) throws MetaborgException {
    final ILanguage strategoLanguage = languageService.getLanguage(SpoofaxConstants.LANG_STRATEGO_NAME);
    if (strategoLanguage == null) {
        final String message = logger.format("Could not find Stratego language, Stratego dialects cannot be identified for resource: {}", resource);
        throw new MetaborgRuntimeException(message);
    }
    // GTODO: use identifier service instead, but that introduces a cyclic dependency. Could use a provider.
    final ILanguageImpl strategoImpl = strategoLanguage.activeImpl();
    if (strategoImpl == null) {
        return null;
    }
    // HACK: assuming single identification facet
    final IdentificationFacet facet = strategoImpl.facet(IdentificationFacet.class);
    if (facet == null || !facet.identify(resource)) {
        return null;
    }
    try {
        final FileObject metaResource = metaResource(resource);
        if (metaResource == null) {
            return null;
        }
        final TermReader termReader = new TermReader(termFactoryService.getGeneric());
        final IStrategoTerm term = termReader.parseFromStream(metaResource.getContent().getInputStream());
        final String name = getSyntaxName(term.getSubterm(0));
        if (name == null) {
            return null;
        }
        final ILanguageImpl dialect = dialectService.getDialect(name);
        if (dialect == null) {
            final String message = String.format("Resource %s requires dialect %s, but that dialect does not exist", resource, name);
            throw new MetaborgException(message);
        }
        final ILanguageImpl base = dialectService.getBase(dialect);
        return new IdentifiedDialect(dialect, base);
    } catch (ParseError | IOException e) {
        throw new MetaborgException("Unable to open or parse .meta file", e);
    }
}
Also used : MetaborgRuntimeException(org.metaborg.core.MetaborgRuntimeException) IStrategoTerm(org.spoofax.interpreter.terms.IStrategoTerm) IdentificationFacet(org.metaborg.core.language.IdentificationFacet) MetaborgException(org.metaborg.core.MetaborgException) IOException(java.io.IOException) ILanguage(org.metaborg.core.language.ILanguage) ILanguageImpl(org.metaborg.core.language.ILanguageImpl) ParseError(org.spoofax.terms.ParseError) FileObject(org.apache.commons.vfs2.FileObject) IdentifiedDialect(org.metaborg.core.language.dialect.IdentifiedDialect) TermReader(org.spoofax.terms.io.binary.TermReader)

Example 2 with IdentifiedDialect

use of org.metaborg.core.language.dialect.IdentifiedDialect in project spoofax by metaborg.

the class ParsePrimitive method call.

@Override
protected IStrategoTerm call(IStrategoTerm current, Strategy[] svars, IStrategoTerm[] tvars, ITermFactory factory, org.spoofax.interpreter.core.IContext strategoContext) throws MetaborgException, IOException {
    // Determine what to parse.
    if (!(current instanceof IStrategoString)) {
        throw new MetaborgException("Cannot parse, input string or file " + current + " is not a string");
    }
    final String stringOrFile = ((IStrategoString) current).stringValue();
    final String text;
    @Nullable final FileObject file;
    final IStrategoTerm isFileTerm = tvars[0];
    if (!(isFileTerm instanceof IStrategoInt)) {
        throw new MetaborgException("Cannot parse, input kind " + isFileTerm + " is not an integer");
    }
    if (((IStrategoInt) isFileTerm).intValue() == 1) {
        file = resourceService.resolve(stringOrFile);
        if (!file.exists() || !file.isFile()) {
            throw new MetaborgException("Cannot parse, input file " + file + " does not exist or is not a file");
        }
        text = sourceTextService.text(file);
    } else {
        file = null;
        text = stringOrFile;
    }
    // Determine which language to parse it with.
    final ILanguageImpl langImpl;
    final IStrategoTerm nameOrGroupIdTerm = tvars[1];
    final IStrategoTerm idTerm = tvars[2];
    final IStrategoTerm versionTerm = tvars[3];
    if (nameOrGroupIdTerm instanceof IStrategoTuple) {
        // No name, groupId, id, and version was set, auto detect language to parse with.
        if (file == null) {
            throw new MetaborgException("Cannot parse a string, no language to parse it with was given");
        }
        final IContext context = metaborgContext(strategoContext);
        if (context != null) {
            langImpl = languageIdentifierService.identify(file, context.project());
        } else {
            langImpl = languageIdentifierService.identify(file);
        }
        if (langImpl == null) {
            throw new MetaborgException("Cannot parse, language for " + file + " could not be identified");
        }
    } else if (idTerm instanceof IStrategoTuple) {
        // No id was set, name is set.
        if (!(nameOrGroupIdTerm instanceof IStrategoString)) {
            throw new MetaborgException("Cannot parse, language name " + nameOrGroupIdTerm + " is not a string");
        }
        final String name = ((IStrategoString) nameOrGroupIdTerm).stringValue();
        final ILanguage lang = languageService.getLanguage(name);
        if (lang == null) {
            throw new MetaborgException("Cannot parse, language " + nameOrGroupIdTerm + " does not exist");
        }
        langImpl = lang.activeImpl();
        if (langImpl == null) {
            throw new MetaborgException("Cannot parse, language " + lang + " has no implementation loaded");
        }
    } else {
        // A groupId, id, and version is set.
        if (!(nameOrGroupIdTerm instanceof IStrategoString)) {
            throw new MetaborgException("Cannot parse, language groupId " + nameOrGroupIdTerm + " is not a string");
        }
        final String groupId = ((IStrategoString) nameOrGroupIdTerm).stringValue();
        if (!(idTerm instanceof IStrategoString)) {
            throw new MetaborgException("Cannot parse, language id " + idTerm + " is not a string");
        }
        final String id = ((IStrategoString) idTerm).stringValue();
        if (!(versionTerm instanceof IStrategoString)) {
            throw new MetaborgException("Cannot parse, language version " + versionTerm + " is not a string");
        }
        final String versionStr = ((IStrategoString) versionTerm).stringValue();
        final LanguageVersion version = LanguageVersion.parse(versionStr);
        final LanguageIdentifier langId = new LanguageIdentifier(groupId, id, version);
        langImpl = languageService.getImpl(langId);
        if (langImpl == null) {
            throw new MetaborgException("Cannot parse, language implementation " + langId + " does not exist");
        }
    }
    // Parse the text.
    final ISpoofaxInputUnit input;
    if (file != null) {
        @Nullable ILanguageImpl dialect;
        try {
            final IdentifiedDialect identifierDialect = dialectIdentifier.identify(file);
            if (identifierDialect != null) {
                dialect = identifierDialect.dialect;
            } else {
                dialect = null;
            }
        } catch (MetaborgException | MetaborgRuntimeException e) {
            // Ignore
            dialect = null;
        }
        input = unitService.inputUnit(file, text, langImpl, dialect);
    } else {
        input = unitService.inputUnit(text, langImpl, null);
    }
    final ISpoofaxParseUnit result = syntaxService.parse(input);
    if (result.valid() && result.success()) {
        return result.ast();
    } else {
        return null;
    }
}
Also used : ISpoofaxParseUnit(org.metaborg.spoofax.core.unit.ISpoofaxParseUnit) MetaborgRuntimeException(org.metaborg.core.MetaborgRuntimeException) IStrategoTerm(org.spoofax.interpreter.terms.IStrategoTerm) IContext(org.metaborg.core.context.IContext) MetaborgException(org.metaborg.core.MetaborgException) IStrategoString(org.spoofax.interpreter.terms.IStrategoString) IStrategoTuple(org.spoofax.interpreter.terms.IStrategoTuple) IStrategoString(org.spoofax.interpreter.terms.IStrategoString) IStrategoInt(org.spoofax.interpreter.terms.IStrategoInt) ILanguage(org.metaborg.core.language.ILanguage) LanguageIdentifier(org.metaborg.core.language.LanguageIdentifier) ILanguageImpl(org.metaborg.core.language.ILanguageImpl) ISpoofaxInputUnit(org.metaborg.spoofax.core.unit.ISpoofaxInputUnit) LanguageVersion(org.metaborg.core.language.LanguageVersion) FileObject(org.apache.commons.vfs2.FileObject) IdentifiedDialect(org.metaborg.core.language.dialect.IdentifiedDialect) Nullable(javax.annotation.Nullable)

Example 3 with IdentifiedDialect

use of org.metaborg.core.language.dialect.IdentifiedDialect in project spoofax by metaborg.

the class LanguageIdentifierService method identifyToResource.

@Override
@Nullable
public IdentifiedResource identifyToResource(FileObject resource, Iterable<? extends ILanguageImpl> impls) {
    // Ignore directories.
    try {
        if (resource.getType() == FileType.FOLDER) {
            return null;
        }
    } catch (FileSystemException e) {
        logger.error("Cannot identify {}, cannot determine its file type", e, resource);
        return null;
    }
    // Try to identify using the dialect identifier first.
    try {
        final IdentifiedDialect dialect = dialectIdentifier.identify(resource);
        if (dialect != null) {
            return new IdentifiedResource(resource, dialect);
        }
    } catch (MetaborgException e) {
        logger.error("Cannot identify dialect of {}", e, resource);
        return null;
    } catch (MetaborgRuntimeException e) {
    // Ignore
    }
    // Identify using identification facet.
    final Set<ILanguage> identifiedLanguages = Sets.newLinkedHashSet();
    ILanguageImpl identifiedImpl = null;
    for (ILanguageImpl impl : impls) {
        if (identify(resource, impl)) {
            identifiedLanguages.add(impl.belongsTo());
            identifiedImpl = impl;
        }
    }
    if (identifiedLanguages.size() > 1) {
        throw new IllegalStateException("Resource " + resource + " identifies to multiple languages: " + Joiner.on(", ").join(identifiedLanguages));
    }
    if (identifiedImpl == null) {
        return null;
    }
    return new IdentifiedResource(resource, null, identifiedImpl);
}
Also used : MetaborgRuntimeException(org.metaborg.core.MetaborgRuntimeException) FileSystemException(org.apache.commons.vfs2.FileSystemException) MetaborgException(org.metaborg.core.MetaborgException) IdentifiedDialect(org.metaborg.core.language.dialect.IdentifiedDialect) Nullable(javax.annotation.Nullable)

Aggregations

MetaborgException (org.metaborg.core.MetaborgException)3 MetaborgRuntimeException (org.metaborg.core.MetaborgRuntimeException)3 IdentifiedDialect (org.metaborg.core.language.dialect.IdentifiedDialect)3 Nullable (javax.annotation.Nullable)2 FileObject (org.apache.commons.vfs2.FileObject)2 ILanguage (org.metaborg.core.language.ILanguage)2 ILanguageImpl (org.metaborg.core.language.ILanguageImpl)2 IStrategoTerm (org.spoofax.interpreter.terms.IStrategoTerm)2 IOException (java.io.IOException)1 FileSystemException (org.apache.commons.vfs2.FileSystemException)1 IContext (org.metaborg.core.context.IContext)1 IdentificationFacet (org.metaborg.core.language.IdentificationFacet)1 LanguageIdentifier (org.metaborg.core.language.LanguageIdentifier)1 LanguageVersion (org.metaborg.core.language.LanguageVersion)1 ISpoofaxInputUnit (org.metaborg.spoofax.core.unit.ISpoofaxInputUnit)1 ISpoofaxParseUnit (org.metaborg.spoofax.core.unit.ISpoofaxParseUnit)1 IStrategoInt (org.spoofax.interpreter.terms.IStrategoInt)1 IStrategoString (org.spoofax.interpreter.terms.IStrategoString)1 IStrategoTuple (org.spoofax.interpreter.terms.IStrategoTuple)1 ParseError (org.spoofax.terms.ParseError)1