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.javascript;
018
019import java.util.List;
020
021import eu.cqse.check.framework.scanner.ETokenType;
022import eu.cqse.check.framework.scanner.IToken;
023import eu.cqse.check.framework.shallowparser.framework.ParserState;
024import eu.cqse.check.framework.shallowparser.framework.RecognizerBase;
025import eu.cqse.check.framework.shallowparser.languages.javascript.JavaScriptShallowParser.EJavaScriptParserStates;
026
027/**
028 * Recognizer for calls of the global YUI object from the YUI framework.
029 */
030public class YuiCallRecognizer extends RecognizerBase<EJavaScriptParserStates> {
031
032        /** Name of the global YUI object. */
033        private static final String YUI = "YUI";
034
035        /** The method name. */
036        private final String methodName;
037
038        /** Constructor. */
039        public YuiCallRecognizer(String methodName) {
040                this.methodName = methodName;
041        }
042
043        /**
044         * {@inheritDoc}
045         * <p>
046         * This matches either "YUI.[methodName]" or "YUI().[methodName]".
047         */
048        @Override
049        protected int matchesLocally(ParserState<EJavaScriptParserStates> parserState, List<IToken> tokens,
050                        int startOffset) {
051
052                if (tokens.size() - startOffset < 3) {
053                        return NO_MATCH;
054                }
055
056                if (!isIdentifier(tokens.get(startOffset), YUI)) {
057                        return NO_MATCH;
058                }
059
060                // optionally skip "()" after "YUI"
061                if (tokens.get(startOffset + 1).getType() == ETokenType.LPAREN) {
062                        if (tokens.get(startOffset + 2).getType() != ETokenType.RPAREN || tokens.size() - startOffset < 5) {
063                                return NO_MATCH;
064                        }
065                        startOffset += 2;
066                }
067
068                if (tokens.get(startOffset + 1).getType() != ETokenType.DOT) {
069                        return NO_MATCH;
070                }
071
072                if (!isIdentifier(tokens.get(startOffset + 2), methodName)) {
073                        return NO_MATCH;
074                }
075
076                return startOffset + 3;
077        }
078
079        /** Returns whether the given token is an identifier of given name. */
080        private static boolean isIdentifier(IToken token, String name) {
081                return token.getType() == ETokenType.IDENTIFIER && token.getText().equals(name);
082        }
083}