eu.cqse.check.framework.shallowparser.languages.objectivecpp.ObjectiveCppShallowParser Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of teamscale-check-api Show documentation
Show all versions of teamscale-check-api Show documentation
The Teamscale Custom Check API allows users to extend Teamscale by writing custom analyses that create findings.
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);
}
}