001/*-------------------------------------------------------------------------+ 002| | 003| Copyright 2005-2011 the ConQAT Project | 004| | 005| Licensed under the Apache License, Version 2.0 (the "License"); | 006| you may not use this file except in compliance with the License. | 007| You may obtain a copy of the License at | 008| | 009| http://www.apache.org/licenses/LICENSE-2.0 | 010| | 011| Unless required by applicable law or agreed to in writing, software | 012| distributed under the License is distributed on an "AS IS" BASIS, | 013| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 014| See the License for the specific language governing permissions and | 015| limitations under the License. | 016+-------------------------------------------------------------------------*/ 017package eu.cqse.check.framework.shallowparser.languages.abap; 018 019import static eu.cqse.check.framework.scanner.ETokenType.DOT; 020import static eu.cqse.check.framework.scanner.ETokenType.ENDMODULE; 021import static eu.cqse.check.framework.scanner.ETokenType.INPUT; 022import static eu.cqse.check.framework.scanner.ETokenType.MODULE; 023import static eu.cqse.check.framework.scanner.ETokenType.OUTPUT; 024 025import java.util.EnumSet; 026import java.util.List; 027 028import eu.cqse.check.framework.scanner.IToken; 029import eu.cqse.check.framework.shallowparser.TokenStreamUtils; 030import eu.cqse.check.framework.shallowparser.framework.ParserState; 031import eu.cqse.check.framework.shallowparser.framework.RecognizerBase; 032import eu.cqse.check.framework.shallowparser.languages.abap.AbapShallowParser.EAbapParserStates; 033 034/** 035 * Precondition recognizer that matches if a module block (not a module 036 * statement) starts at the current location, but does not consume any tokens. A 037 * module block starts with one of: 038 * 039 * <pre> 040 * module x. 041 * module x input. 042 * module x output. 043 * </pre> 044 * 045 * and ends with <code>endmodule</code>. 046 * <p> 047 * This recognizer is used to distinguish module statements (that invoke a 048 * module) from module declarations (matched by this recognizer). 049 * <p> 050 * Note that module statements cannot appear inside module blocks. 051 */ 052public class ModuleBlockStartRecognizer extends RecognizerBase<EAbapParserStates> { 053 054 /** {@inheritDoc} */ 055 @Override 056 protected int matchesLocally(ParserState<EAbapParserStates> parserState, List<IToken> tokens, int startOffset) { 057 if (tokens.size() < startOffset + 3) { 058 return NO_MATCH; 059 } 060 061 if (tokens.get(startOffset).getType() != MODULE) { 062 return NO_MATCH; 063 } 064 065 if (!EnumSet.of(DOT, INPUT, OUTPUT).contains(tokens.get(startOffset + 2).getType())) { 066 return NO_MATCH; 067 } 068 069 int endModuleIndex = TokenStreamUtils.firstTokenOfType(tokens, startOffset, ENDMODULE); 070 if (endModuleIndex == -1) { 071 return NO_MATCH; 072 } 073 074 int moduleIndex = TokenStreamUtils.firstTokenOfType(tokens, startOffset + 1, MODULE); 075 if (moduleIndex != -1 && moduleIndex < endModuleIndex) { 076 return NO_MATCH; 077 } 078 079 return startOffset; 080 } 081}