All Downloads are FREE. Search and download functionalities are using the official Maven repository.

eu.cqse.check.framework.shallowparser.languages.objectivecpp.ObjectiveCppShallowParser Maven / Gradle / Ivy

Go to download

The Teamscale Custom Check API allows users to extend Teamscale by writing custom analyses that create findings.

There is a newer version: 2024.7.2
Show newest version
package eu.cqse.check.framework.shallowparser.languages.objectivecpp;

import static eu.cqse.check.framework.scanner.ETokenType.AND;
import static eu.cqse.check.framework.scanner.ETokenType.ANDAND;
import static eu.cqse.check.framework.scanner.ETokenType.AUTORELEASEPOOL;
import static eu.cqse.check.framework.scanner.ETokenType.CLASS;
import static eu.cqse.check.framework.scanner.ETokenType.CONST;
import static eu.cqse.check.framework.scanner.ETokenType.CONSTEXPR;
import static eu.cqse.check.framework.scanner.ETokenType.FAR;
import static eu.cqse.check.framework.scanner.ETokenType.IDENTIFIER;
import static eu.cqse.check.framework.scanner.ETokenType.IMPORT;
import static eu.cqse.check.framework.scanner.ETokenType.LBRACE;
import static eu.cqse.check.framework.scanner.ETokenType.LBRACK;
import static eu.cqse.check.framework.scanner.ETokenType.LPAREN;
import static eu.cqse.check.framework.scanner.ETokenType.MULT;
import static eu.cqse.check.framework.scanner.ETokenType.MUTABLE;
import static eu.cqse.check.framework.scanner.ETokenType.NEAR;
import static eu.cqse.check.framework.scanner.ETokenType.NONNULL;
import static eu.cqse.check.framework.scanner.ETokenType.NULLABLE;
import static eu.cqse.check.framework.scanner.ETokenType.RBRACE;
import static eu.cqse.check.framework.scanner.ETokenType.RBRACK;
import static eu.cqse.check.framework.scanner.ETokenType.REQUIRES;
import static eu.cqse.check.framework.scanner.ETokenType.RPAREN;
import static eu.cqse.check.framework.scanner.ETokenType.SEMICOLON;
import static eu.cqse.check.framework.scanner.ETokenType.TEMPLATE;
import static eu.cqse.check.framework.scanner.ETokenType.TYPENAME;
import static eu.cqse.check.framework.scanner.ETokenType.VOLATILE;
import static eu.cqse.check.framework.scanner.ETokenType.XOR;
import static eu.cqse.check.framework.shallowparser.framework.EShallowEntityType.META;
import static eu.cqse.check.framework.shallowparser.languages.base.EGenericParserStates.IN_EXPRESSION;
import static eu.cqse.check.framework.shallowparser.languages.base.EGenericParserStates.IN_METHOD;

import java.util.EnumSet;
import java.util.List;
import java.util.Set;

import org.conqat.lib.commons.region.Region;

import eu.cqse.check.framework.scanner.ETokenType;
import eu.cqse.check.framework.scanner.IToken;
import eu.cqse.check.framework.shallowparser.SubTypeNames;
import eu.cqse.check.framework.shallowparser.framework.EShallowEntityType;
import eu.cqse.check.framework.shallowparser.framework.RecognizerBase;
import eu.cqse.check.framework.shallowparser.languages.base.CStyleShallowParserBase;
import eu.cqse.check.framework.shallowparser.languages.base.EGenericParserStates;
import eu.cqse.check.framework.shallowparser.languages.cpp.CppLambdaRecognizer;
import eu.cqse.check.framework.shallowparser.languages.cpp.CppShallowParser;
import eu.cqse.check.framework.shallowparser.languages.cpp.CppShallowParserAdditionalStatementRules;
import eu.cqse.check.framework.shallowparser.languages.cpp.CppShallowParserBasicBlockRules;
import eu.cqse.check.framework.shallowparser.languages.cpp.CppShallowParserCaseRules;
import eu.cqse.check.framework.shallowparser.languages.cpp.CppShallowParserClassElementRules;
import eu.cqse.check.framework.shallowparser.languages.cpp.CppShallowParserMetaRules;
import eu.cqse.check.framework.shallowparser.languages.cpp.CppShallowParserNamespaceRules;
import eu.cqse.check.framework.shallowparser.languages.cpp.CppShallowParserTypeRules;
import eu.cqse.check.framework.shallowparser.languages.cpp.CppSkipTemplateSpecificationRecognizer;
import eu.cqse.check.framework.shallowparser.languages.objectivec.AppleBlockSyntaxRecognizer;
import eu.cqse.check.framework.shallowparser.languages.objectivec.ObjectiveCBlockRules;
import eu.cqse.check.framework.shallowparser.languages.objectivec.ObjectiveCClassElementRules;
import eu.cqse.check.framework.shallowparser.languages.objectivec.ObjectiveCShallowParser;
import eu.cqse.check.framework.shallowparser.languages.objectivec.ObjectiveCTypeRules;

public class ObjectiveCppShallowParser extends CStyleShallowParserBase {

	/** The following keywords may be used as label names in Objective-C++ */
	public static final EnumSet VALID_OBJECTIVE_CPP_IDENTIFIERS = EnumSet.of(REQUIRES, MUTABLE, TEMPLATE,
			CLASS);

	public ObjectiveCppShallowParser() {
		new CppShallowParserNamespaceRules(this).contributeRules();
		new ObjectiveCBlockRules(this).contributeRules();
	}

	@Override
	protected void createClassElementsRules() {
		new CppShallowParserClassElementRules(this).contributeRules();
		new ObjectiveCClassElementRules(this).contributeRules();
	}

	@Override
	protected void createTypeRules() {
		createTypedefRules();
		new CppShallowParserTypeRules(this).contributeRules();
		new ObjectiveCTypeRules(this).contributeRules();
	}

	@Override
	public EnumSet getValidIdentifiers() {
		EnumSet validIdentifiers = EnumSet.copyOf(ObjectiveCShallowParser.VALID_OBJECTIVE_C_IDENTIFIERS);
		validIdentifiers.addAll(CppShallowParser.VALID_IDENTIFIERS);
		validIdentifiers.addAll(VALID_OBJECTIVE_CPP_IDENTIFIERS);
		return validIdentifiers;
	}

	@Override
	protected void createMetaRules() {
		new CppShallowParserMetaRules(this).contributeRules();
		inAnyState().sequence(IMPORT).skipTo(SEMICOLON).createNode(META, SubTypeNames.IMPORT, new Region(1, -2))
				.endNode();
		super.createMetaRules();
	}

	@Override
	protected void createBasicBlockRules() {
		new CppShallowParserBasicBlockRules(this).contributeRules();
		super.createBasicBlockRules();
	}

	@Override
	protected RecognizerBase getBlockRuleStart() {
		return super.getBlockRuleStart().repeatedSubRecognizer(CppShallowParser.createAnnotationSubrecognizer())
				.markStart();
	}

	@Override
	protected void createCaseRule() {
		new CppShallowParserCaseRules(this).contributeRules();
	}

	@Override
	protected void createSubExpressionRules() {
		CppShallowParser.startLambdaRule(inState(IN_EXPRESSION), getTypeKeywords(),
				CppShallowParser.TYPE_OR_IDENTIFIER);

		// Objective-C rule for block expressions (similar to lambdas)
		inState(IN_EXPRESSION).sequence(XOR).createNode(EShallowEntityType.METHOD, SubTypeNames.BLOCK_EXPRESSION, null)
				.skipToWithNesting(LBRACE, LPAREN, RPAREN).parseUntil(IN_METHOD).sequence(RBRACE).endNode();
	}

	@Override
	protected Set getOptionalTokensBeforeBlockBraces() {
		return EnumSet.of(AUTORELEASEPOOL);
	}

	@Override
	protected EnumSet getTypeKeywords() {
		return CppShallowParser.TYPE_KEYWORDS;
	}

	@Override
	protected EnumSet getSimpleBlockKeywordsWithParentheses() {
		return ObjectiveCShallowParser.SIMPLE_BLOCK_KEYWORDS_WITH_PARENTHESES;
	}

	@Override
	protected EnumSet getSimpleBlockKeywordsWithoutParentheses() {
		return ObjectiveCShallowParser.SIMPLE_BLOCK_KEYWORDS_WITHOUT_PARENTHESES;
	}

	@Override
	protected void createRuleForSimpleStatementHavingStartTokens(Set statementStartTokens) {
		completeSimpleStatement(
				inState(IN_METHOD).repeatedSubRecognizer(CppShallowParser.createAnnotationSubrecognizer()).markStart()
						.sequence(statementStartTokens));
	}

	@Override
	public EnumSet getStatementStartTokens() {
		EnumSet statementStartTokens = EnumSet.copyOf(ObjectiveCShallowParser.STATEMENT_START_TOKENS);
		statementStartTokens.addAll(CppShallowParser.VALID_IDENTIFIERS);
		statementStartTokens.addAll(ObjectiveCShallowParser.VALID_OBJECTIVE_C_IDENTIFIERS);
		statementStartTokens.addAll(VALID_OBJECTIVE_CPP_IDENTIFIERS);
		statementStartTokens.addAll(CppShallowParser.ADDITIONAL_STATEMENT_START_TOKENS);

		// we explicitly remove the LBRACK and handle it separately in
		// #createSimpleStatementRule to avoid mixing with C++11 annotations
		statementStartTokens.remove(LBRACK);
		return statementStartTokens;
	}

	@Override
	protected void createSimpleStatementRule() {
		new CppShallowParserAdditionalStatementRules(this).contributeRules();

		// match a single LBRACK, but not a double one to avoid mixing with C++11
		// annotations
		completeSimpleStatement(
				inState(IN_METHOD).sequence(LBRACK).notPreCondition(createRecognizer(start -> start.sequence(LBRACK))));
	}

	@Override
	public RecognizerBase typePattern(RecognizerBase currentState) {
		EnumSet extendedTypeKeywords = EnumSet.copyOf(getTypeKeywords());
		extendedTypeKeywords.add(TYPENAME);

		// The XOR clause is added to support the handle declarator (^) from
		// Microsoft's C++/CLI, e.g. "FooClass^"
		return currentState.repeatedSubRecognizer(CppShallowParser.createAnnotationSubrecognizer())
				.repeated(CppShallowParser.METHOD_AND_TYPE_DECLARATION_MODIFIERS).skipNested(LPAREN, RPAREN)
				.optional(extendedTypeKeywords).skipNested(LPAREN, RPAREN)
				.repeatedSubRecognizer(createScopeRecognizer())
				.subRecognizer(CppShallowParser.createPrimitiveOrIdentifierMatcher(CppShallowParser.PRIMITIVE_TYPES))
				.subRecognizer(new CppSkipTemplateSpecificationRecognizer(), 0, 1)
				.skipAny(EnumSet.of(MULT, AND, ANDAND, CONST, CONSTEXPR, XOR, VOLATILE, NONNULL, NULLABLE))
				.skipNested(LBRACK, RBRACK)
				.skipAny(EnumSet.of(MULT, AND, ANDAND, CONST, CONSTEXPR, XOR, LBRACK, RBRACK, NEAR, FAR));
	}

	@Override
	public RecognizerBase getSubExpressionRecognizer() {
		return createRecognizer(start -> {
			// chain both recognizers, one after the other
			start.subRecognizer(new AppleBlockSyntaxRecognizer());
			start.subRecognizer(new CppLambdaRecognizer(CppShallowParser.TYPE_OR_IDENTIFIER));
		});
	}

	@Override
	protected List filterTokens(List tokens) {
		List result = super.filterTokens(tokens);
		result = CppShallowParser.filterGCCAttributes(result);
		result = CppShallowParser.filterMicrosoftSpecificAttribute(result);
		return result;
	}

	@Override
	protected boolean isFilteredToken(IToken token, IToken previousToken) {
		if (token.getType() == IDENTIFIER && CppShallowParser.PSEUDO_KEYWORDS.contains(token.getText())) {
			return true;
		}

		return super.isFilteredToken(token, previousToken);
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy