eu.numberfour.n4js.tests.GrammarLinter.java Source code

Java tutorial

Introduction

Here is the source code for eu.numberfour.n4js.tests.GrammarLinter.java

Source

/**
 * Copyright (c) 2016 NumberFour AG.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *   NumberFour AG - Initial API and implementation
 */
package eu.numberfour.n4js.tests;

import static org.eclipse.xtext.EcoreUtil2.eAllContentsAsList;
import static org.eclipse.xtext.EcoreUtil2.typeSelect;

import java.util.Collection;
import java.util.List;

import org.eclipse.xtext.AbstractRule;
import org.eclipse.xtext.EcoreUtil2;
import org.eclipse.xtext.EnumRule;
import org.eclipse.xtext.Grammar;
import org.eclipse.xtext.GrammarUtil;
import org.eclipse.xtext.Keyword;
import org.eclipse.xtext.ParserRule;

import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.ListMultimap;
import com.google.inject.Inject;

import eu.numberfour.n4js.N4JSStandaloneSetup;
import eu.numberfour.n4js.services.N4JSGrammarAccess;
import eu.numberfour.n4js.ts.TypeExpressionsStandaloneSetup;
import eu.numberfour.n4js.ts.services.TypeExpressionsGrammarAccess;

/**
 * Small helper to identifiy potential programming problems in the grammar.
 */
public class GrammarLinter {

    @Inject
    private N4JSGrammarAccess grammarAccess;
    private TypeExpressionsGrammarAccess typesGrammarAccess;

    /***/
    public static void main(String[] args) {
        GrammarLinter linter = new N4JSStandaloneSetup().createInjectorAndDoEMFRegistration()
                .getInstance(GrammarLinter.class);
        linter.typesGrammarAccess = new TypeExpressionsStandaloneSetup().createInjector()
                .getInstance(TypeExpressionsGrammarAccess.class);
        linter.diagnose();
    }

    /***/
    public void diagnose() {
        printKeywordsOnlyInDatatypeRules();
        printKeywordsInTypesButNotInN4JS();
    }

    private void printKeywordsInTypesButNotInN4JS() {
        Grammar n4js = grammarAccess.getGrammar();
        Grammar types = typesGrammarAccess.getGrammar();
        ListMultimap<String, Keyword> n4jsKeywords = getAllKeywords(n4js);
        ListMultimap<String, Keyword> typesKeywords = getAllKeywords(types);

        typesKeywords.keySet().removeAll(n4jsKeywords.keySet());

        System.out.println("Keywords which do not occur in n4js rules: ");
        for (String keyword : typesKeywords.keySet()) {
            System.out.println("  " + keyword);
        }
        System.out.println();
    }

    private void printKeywordsOnlyInDatatypeRules() {
        Grammar grammar = grammarAccess.getGrammar();
        ListMultimap<String, Keyword> allKeywords = getAllKeywords(grammar);
        System.out.println("Keywords which do not occur in production rules: ");
        outer: for (Collection<Keyword> chunk : allKeywords.asMap().values()) {
            for (Keyword keyword : chunk) {
                AbstractRule rule = EcoreUtil2.getContainerOfType(keyword, AbstractRule.class);
                if (!GrammarUtil.isDatatypeRule(rule)) {
                    continue outer;
                }
            }
            System.out.println("  " + ((List<Keyword>) chunk).get(0).getValue());
        }
        System.out.println();
    }

    private static ListMultimap<String, Keyword> getAllKeywords(Grammar g) {
        ListMultimap<String, Keyword> keywords = ArrayListMultimap.create();
        List<ParserRule> rules = GrammarUtil.allParserRules(g);
        for (ParserRule parserRule : rules) {
            List<Keyword> list = typeSelect(eAllContentsAsList(parserRule), Keyword.class);
            for (Keyword keyword : list) {
                keywords.put(keyword.getValue(), keyword);
            }
        }
        List<EnumRule> enumRules = GrammarUtil.allEnumRules(g);
        for (EnumRule enumRule : enumRules) {
            List<Keyword> list = typeSelect(eAllContentsAsList(enumRule), Keyword.class);
            for (Keyword keyword : list) {
                keywords.put(keyword.getValue(), keyword);
            }
        }
        return keywords;
    }

}