tracefw/tracecompiler/src/com.nokia.tracecompiler/src/com/nokia/tracecompiler/source/ContextAreaParser.java
changeset 56 aa2539c91954
parent 54 a151135b0cf9
child 60 e54443a6878c
child 62 1c2bb2fc7c87
--- a/tracefw/tracecompiler/src/com.nokia.tracecompiler/src/com/nokia/tracecompiler/source/ContextAreaParser.java	Wed Sep 29 17:45:35 2010 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,521 +0,0 @@
-/*
-* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). 
-* All rights reserved.
-* This component and the accompanying materials are made available
-* under the terms of "Eclipse Public License v1.0"
-* which accompanies this distribution, and is available
-* at the URL "http://www.eclipse.org/legal/epl-v10.html".
-*
-* Initial Contributors:
-* Nokia Corporation - initial contribution.
-*
-* Contributors:
-*
-* Description:
-*
-* Parser for source contexts
-*
-*/
-package com.nokia.tracecompiler.source;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.List;
-
-/**
- * Parser for source contexts
- * 
- */
-class ContextAreaParser {
-
-	/**
-	 * Source parser
-	 */
-	private SourceParser parser;
-
-	/**
-	 * List of source file contexts
-	 */
-	protected ArrayList<SourceContext> contextAreas = new ArrayList<SourceContext>();
-
-	/**
-	 * Comparator for array sorting and searching
-	 */
-	private PositionArrayComparator arrayComparator = new PositionArrayComparator();
-
-	/**
-	 * "usingnamespace" text
-	 */
-	private static final String USINGNAMESPACE = "usingnamespace"; //$NON-NLS-1$
-
-	/**
-	 * Start index of "using" substring in "usingnamespace" string
-	 */
-	private static final int START_INDEX_OF_USING_SUBSTRING = 0; // CodForChk_Dis_Magic
-
-	/**
-	 * End index of "using" substring in "usingnamespace" string
-	 */
-	private static final int END_INDEX_OF_USING_SUBSTRING = 5; // CodForChk_Dis_Magic
-
-	/**
-	 * Start index of "namespace" substring in "usingnamespace" string
-	 */
-	private static final int START_INDEX_OF_NAMESPACE_SUBSTRING = 5; // CodForChk_Dis_Magic
-
-	/**
-	 * End index of "namespace" substring in "usingnamespace" string
-	 */
-	private static final int END_INDEX_OF_NAMESPACE_SUBSTRING = 14; // CodForChk_Dis_Magic
-
-	/**
-	 * Constructor
-	 * 
-	 * @param parser
-	 *            the source parser
-	 */
-	ContextAreaParser(SourceParser parser) {
-		this.parser = parser;
-	}
-
-	/**
-	 * Resets the context areas
-	 */
-	void reset() {
-		contextAreas.clear();
-	}
-
-	/**
-	 * Returns the context at given offset
-	 * 
-	 * @param offset
-	 *            the offset to the source data
-	 * @return the context at the offset or null if no context exists
-	 * @throws SourceParserException
-	 *             if parser fails
-	 */
-	SourceContext parseAndGet(int offset) throws SourceParserException {
-		if (contextAreas.isEmpty()) {
-			parseAll();
-		}
-		int index = find(offset);
-		SourceContext context = null;
-		if (index >= 0) {
-			context = contextAreas.get(index);
-		}
-		return context;
-	}
-
-	/**
-	 * Gets the context areas. If the areas have not been parsed, this parses
-	 * them
-	 * 
-	 * @return the areas
-	 * @throws SourceParserException
-	 *             if parser fails
-	 */
-	Iterator<SourceContext> parseAndGetAll() throws SourceParserException {
-		if (contextAreas.isEmpty()) {
-			parseAll();
-		}
-		return contextAreas.iterator();
-	}
-
-	/**
-	 * Gets the context area list. This does not parse the areas
-	 * 
-	 * @return the list of context areas
-	 */
-	List<SourceContext> getContextList() {
-		return contextAreas;
-	}
-
-	/**
-	 * Finds the array index of the context area which contains the offset. If
-	 * none of the areas contain the offset, returns negative integer indicating
-	 * the index of the context area following the offset
-	 * 
-	 * @param offset
-	 *            the offset to the data
-	 * @return the context area index
-	 */
-	int find(int offset) {
-		return Collections.binarySearch(contextAreas, new SourceLocationBase(
-				parser, offset), arrayComparator);
-	}
-
-	/**
-	 * Builds the context array
-	 * 
-	 * @throws SourceParserException
-	 *             if parser fails
-	 */
-	void parseAll() throws SourceParserException { // CodForChk_Dis_ComplexFunc
-		contextAreas.clear();
-		char value;
-		
-		int inBrackets = 0;
-		int inContext = 0;
-		int inNamespace = 0;
-
-		int usingIndex = START_INDEX_OF_USING_SUBSTRING;
-		int usingKeywordEnd = 0;
-		int namespaceIndex = START_INDEX_OF_NAMESPACE_SUBSTRING;
-		int nameSpaceKeywordEnd = 0;
-		int previousIndexBeforeNamespace = 0;
-		boolean checkNextCharacter = false;
-
-		SourceContext context = null;
-		SourceIterator itr = parser.createIterator(0, SourceParser.SKIP_ALL);
-
-		while (itr.hasNext()) {
-			value = itr.next();
-
-			// Next character check is need only if we have found "namespace"
-			// text
-			if (checkNextCharacter) {
-
-				// Next character after "namespace" text should be space.
-				// Because we have skipped spaces, current index should be
-				// bigger than nameSpaceKeywordEnd + 1. If it is not space then
-				// we are not inside namespace
-				if (itr.currentIndex() - nameSpaceKeywordEnd < 2) { // CodForChk_Dis_Magic
-					inNamespace--;
-				}
-				checkNextCharacter = false;
-			}
-
-			// Check is character part of "using" text
-			if (value == USINGNAMESPACE.charAt(usingIndex)) {
-				usingIndex++;
-			} else {
-
-				// Character not part of "using" text -> reset usingIndex
-				usingIndex = START_INDEX_OF_USING_SUBSTRING;
-			}
-
-			// Check that did we found "using" text
-			if (usingIndex == END_INDEX_OF_USING_SUBSTRING) {
-				usingKeywordEnd = itr.currentIndex();
-				usingIndex = START_INDEX_OF_USING_SUBSTRING;
-			}
-
-			// Check is character part of "namespace" text
-			if (value == USINGNAMESPACE.charAt(namespaceIndex)) {
-				if (previousIndexBeforeNamespace == 0) {
-					previousIndexBeforeNamespace = itr.previousIndex();
-				}
-				namespaceIndex++;
-			} else {
-
-				// Character not part of "namespace" text -> reset
-				// previousIndexBeforeNamespace and namespaceIndex
-				previousIndexBeforeNamespace = 0;
-				namespaceIndex = START_INDEX_OF_NAMESPACE_SUBSTRING;
-			}
-
-			// Check that did we found "namespace" text
-			if (namespaceIndex == END_INDEX_OF_NAMESPACE_SUBSTRING) {
-				nameSpaceKeywordEnd = itr.currentIndex();
-
-				// If there was "using" text just before "namespace" text, then
-				// namespace is defined like: "using namespace foo;" and we are
-				// not going inside namespace brackets
-				if (usingKeywordEnd != previousIndexBeforeNamespace) {
-					inNamespace++;
-					checkNextCharacter = true;
-				}
-				namespaceIndex = START_INDEX_OF_NAMESPACE_SUBSTRING;
-			}
-
-			if (value == '{') {
-				inBrackets++;
-
-				// Check that are we inside namespace or context
-				if (inBrackets > inNamespace) {
-					inContext++;
-					if (inContext == 1) {
-						int start = itr.currentIndex() + 1;
-						context = new SourceContext(parser, start);
-
-						// Includes the '{' character into the context
-						if (!createContext(context, start - 2)) { // CodForChk_Dis_Magic
-							context = null;
-						}
-					}
-				}
-			} else if (value == '}') {
-				// Check that are we exiting from context or namespace
-				if (inBrackets == inNamespace) {
-					inNamespace--;
-				} else {
-					inContext--;
-					if (inContext == 0 && context != null) {
-						context.setLength(itr.currentIndex() + 1
-								- context.getOffset());
-						contextAreas.add(context);
-					}
-				}
-
-				inBrackets--;
-			}
-		}
-	}
-
-	/**
-	 * Sets the data to the source context
-	 * 
-	 * @param context
-	 *            the source context to be updated
-	 * @param offset
-	 *            the index preceeding the '{' character
-	 * @return true if valid, false otherwise
-	 * @throws SourceParserException
-	 *             if processing fails
-	 */
-	private boolean createContext(SourceContext context, int offset)
-			throws SourceParserException {
-		ContextSearchData data = new ContextSearchData();
-		data.itr = parser.createIterator(offset, SourceParser.BACKWARD_SEARCH
-				| SourceParser.SKIP_ALL);
-		data.context = context;
-		while (data.itr.hasNext() && !data.finished) {
-			char c = data.itr.next();
-			// Function start or stop character or statement separator breaks
-			// the search in normal case. In case of nested class separator
-			// character breaks the search.
-			if (c == ';' || c == '}' || c == '{'
-					|| (c == ':' && data.itr.peek() == ':')
-					&& data.classStartIndex != -1) {
-				processContextTerminator(context, data, false);
-			} else if (!data.parametersFound) {
-				processParametersNotFoundCharacter(data, c);
-			} else if (c == ')' || c == '(' || c == ','
-					|| (c == ':' && data.itr.peek() != ':')) {
-				// Constructor member initializer list may contain brackets, ','
-				// and ':'. When one of the characters from member initializer
-				// list is encountered, this assumes that the previous
-				// one was not the actual function parameter list yet. All
-				// variables are reset in that case
-				data.parametersFound = false;
-				data.functionEndIndex = -1;
-				data.functionStartIndex = -1;
-				data.classEndIndex = -1;
-				processParametersNotFoundCharacter(data, c);
-			} else if (data.functionEndIndex == -1) {
-				processFunctionNameNotFoundCharacter(data, c);
-			} else if (data.functionStartIndex == -1) {
-				processFunctionNameCharacter(context, data, c);
-			} else if (data.classEndIndex == -1) {
-				processClassNameNotFoundCharacter(data);
-			} else if (data.classStartIndex == -1) {
-				processClassNameCharacter(context, data, c);
-			} else {
-				processReturnTypeCharacter(context, data);
-			}
-		}
-		if (!data.finished) {
-			processContextTerminator(context, data, true);
-		}
-		return data.valid;
-	}
-
-	/**
-	 * Processes a character after class and function names have been found
-	 * 
-	 * @param context
-	 *            the context
-	 * @param data
-	 *            the search data
-	 * @throws SourceParserException
-	 *             if processing fails
-	 */
-	private void processReturnTypeCharacter(SourceContext context,
-			ContextSearchData data) throws SourceParserException {
-		if (data.itr.hasSkipped()) {
-			// Collects all return type candidates to the context
-			addReturnType(context, data.itr.previousIndex(),
-					data.returnEndIndex);
-			data.returnEndIndex = data.itr.currentIndex();
-		}
-	}
-
-	/**
-	 * Processes a character after function name has been found, but class name
-	 * has not yet been found
-	 * 
-	 * @param data
-	 *            the search flags
-	 */
-	private void processClassNameNotFoundCharacter(ContextSearchData data) {
-		// After start of function and the separator has been found, the
-		// next character marks the end of class name
-		data.classEndIndex = data.itr.currentIndex() + 1;
-	}
-
-	/**
-	 * Parses a character which belongs to the class name
-	 * 
-	 * @param context
-	 *            the source context to be parsed
-	 * @param data
-	 *            the context search parameters
-	 * @param c
-	 *            the character
-	 * @throws SourceParserException
-	 *             if processing fails
-	 */
-	private void processClassNameCharacter(SourceContext context,
-			ContextSearchData data, char c) throws SourceParserException {
-		if (data.itr.hasSkipped() || (c == ':' && data.itr.peek() == ':')) {
-			// Start of class name is found when iterator skips over
-			// white space or comment characters or in case of nested class
-			// separator character has been found
-			context.setFunctionName(parser.getSource().get(
-					data.functionStartIndex,
-					data.functionEndIndex - data.functionStartIndex));
-			data.classStartIndex = data.itr.previousIndex();
-			data.returnEndIndex = data.itr.currentIndex();
-			context.setClassName(parser.getSource().get(data.classStartIndex,
-					data.classEndIndex - data.classStartIndex));
-
-			// In case of nested class skips over the second ':'
-			if (c == ':' && data.itr.peek() == ':') {
-				data.itr.next();
-			}
-		}
-	}
-
-	/**
-	 * Processes a character while within function name
-	 * 
-	 * @param context
-	 *            the source context under processing
-	 * @param data
-	 *            the context search flags
-	 * @param c
-	 *            the character
-	 * @throws SourceParserException
-	 *             if processing fails
-	 */
-	private void processFunctionNameCharacter(SourceContext context,
-			ContextSearchData data, char c) throws SourceParserException {
-		// After end of function has been found the separator character
-		// marks the start of function
-		if (c == ':') {
-			if (data.itr.hasNext() && data.itr.peek() == ':') {
-				data.functionStartIndex = data.itr.previousIndex();
-				context.setFunctionName(parser.getSource().get(
-						data.functionStartIndex,
-						data.functionEndIndex - data.functionStartIndex));
-				// Skips over the second ':'
-				data.itr.next();
-			} else {
-				// Only one ':' character -> Invalid
-				data.finished = true;
-			}
-		} else if (data.itr.hasSkipped()) {
-			// If the iterator skipped over some characters and the next
-			// character is not ':' the function is a non-member
-			data.functionStartIndex = data.itr.previousIndex();
-			context.setFunctionName(parser.getSource().get(
-					data.functionStartIndex,
-					data.functionEndIndex - data.functionStartIndex));
-			// Class name indices are set so parser does not search for them
-			data.classStartIndex = data.itr.previousIndex();
-			data.classEndIndex = data.itr.previousIndex();
-			data.returnEndIndex = data.itr.currentIndex();
-		}
-	}
-
-	/**
-	 * Processes a character when function name has not yet been found
-	 * 
-	 * @param data
-	 *            the search flags
-	 * @param c
-	 *            the character to be processed
-	 */
-	private void processFunctionNameNotFoundCharacter(ContextSearchData data,
-			char c) {
-		// The next character after parameters is the end of function
-		if (c == ':') {
-			data.finished = true;
-		}
-		data.functionEndIndex = data.itr.currentIndex() + 1;
-	}
-
-	/**
-	 * Checks if the character is '(' or ')' and updates the parametersFound
-	 * flag accordingly
-	 * 
-	 * @param data
-	 *            the search data
-	 * @param c
-	 *            the current character
-	 */
-	private void processParametersNotFoundCharacter(ContextSearchData data,
-			char c) {
-		if (c == ')') {
-			data.inParameters++;
-		} else if (c == '(') {
-			data.inParameters--;
-			if (data.inParameters == 0) {
-				data.context.setParametersStartIndex(data.itr.currentIndex());
-				data.parametersFound = true;
-			}
-		}
-	}
-
-	/**
-	 * Processes a context terminating character
-	 * 
-	 * @param context
-	 *            the context under processing
-	 * @param data
-	 *            the search data
-	 * @param startOfFile
-	 *            context was terminated due to start of file
-	 * @throws SourceParserException
-	 *             if processing fails
-	 */
-	private void processContextTerminator(SourceContext context,
-			ContextSearchData data, boolean startOfFile)
-			throws SourceParserException {
-		int offset = startOfFile ? data.itr.currentIndex() : data.itr
-				.previousIndex();
-		if (data.classStartIndex != -1) {
-			addReturnType(context, offset, data.returnEndIndex);
-			data.valid = true;
-		} else if (data.classEndIndex != -1) {
-			context.setClassName(parser.getSource().get(offset,
-					data.classEndIndex - offset));
-			data.valid = true;
-		} else if (data.functionEndIndex != -1) {
-			context.setFunctionName(parser.getSource().get(offset,
-					data.functionEndIndex - offset));
-			data.valid = true;
-		}
-		// Finished flag is set. If function name was not found, the valid flag
-		// remains false
-		data.finished = true;
-	}
-
-	/**
-	 * Adds a return type to the context
-	 * 
-	 * @param context
-	 *            the context to be searched
-	 * @param start
-	 *            the start index
-	 * @param end
-	 *            the end index
-	 * @throws SourceParserException
-	 *             if return type cannot be added
-	 */
-	private void addReturnType(SourceContext context, int start, int end)
-			throws SourceParserException {
-		context.addReturnType(parser.getSource().get(start, end - start + 1));
-	}
-}