/*******************************************************************************
 * Copyright (c) 2010 xored software, Inc.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 * 
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     xored software, Inc. - initial API and Implementation (Alex Panchenko)
 *******************************************************************************/
package org.eclipse.dltk.internal.javascript.ti;

import java.text.ParseException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Set;

import org.antlr.runtime.ANTLRStringStream;
import org.antlr.runtime.CharStream;
import org.eclipse.dltk.annotations.NonNull;
import org.eclipse.dltk.annotations.Nullable;
import org.eclipse.dltk.ast.ASTNode;
import org.eclipse.dltk.compiler.problem.IProblemCategory;
import org.eclipse.dltk.compiler.problem.IProblemIdentifier;
import org.eclipse.dltk.compiler.problem.ProblemCategoryManager;
import org.eclipse.dltk.javascript.ast.BinaryOperation;
import org.eclipse.dltk.javascript.ast.CallExpression;
import org.eclipse.dltk.javascript.ast.Comment;
import org.eclipse.dltk.javascript.ast.FunctionStatement;
import org.eclipse.dltk.javascript.ast.IVariableStatement;
import org.eclipse.dltk.javascript.ast.JSNode;
import org.eclipse.dltk.javascript.ast.PropertyExpression;
import org.eclipse.dltk.javascript.ast.PropertyInitializer;
import org.eclipse.dltk.javascript.ast.Statement;
import org.eclipse.dltk.javascript.ast.VariableDeclaration;
import org.eclipse.dltk.javascript.ast.VariableStatement;
import org.eclipse.dltk.javascript.core.JavaScriptLanguageUtil;
import org.eclipse.dltk.javascript.core.JavaScriptNature;
import org.eclipse.dltk.javascript.parser.JSParser;
import org.eclipse.dltk.javascript.parser.JSProblemIdentifier;
import org.eclipse.dltk.javascript.parser.JSProblemReporter;
import org.eclipse.dltk.javascript.parser.ProblemReporter;
import org.eclipse.dltk.javascript.parser.jsdoc.JSDocTag;
import org.eclipse.dltk.javascript.parser.jsdoc.JSDocTags;
import org.eclipse.dltk.javascript.parser.jsdoc.SimpleJSDocParser;
import org.eclipse.dltk.javascript.typeinference.ReferenceLocation;
import org.eclipse.dltk.javascript.typeinfo.IModelBuilder;
import org.eclipse.dltk.javascript.typeinfo.ITypeChecker;
import org.eclipse.dltk.javascript.typeinfo.ITypeInfoContext;
import org.eclipse.dltk.javascript.typeinfo.JSDocParseException;
import org.eclipse.dltk.javascript.typeinfo.JSDocTypeParser;
import org.eclipse.dltk.javascript.typeinfo.model.JSType;
import org.eclipse.dltk.javascript.typeinfo.model.Member;
import org.eclipse.dltk.javascript.typeinfo.model.ParameterKind;
import org.eclipse.dltk.javascript.typeinfo.model.RecordProperty;
import org.eclipse.dltk.javascript.typeinfo.model.RecordType;
import org.eclipse.dltk.javascript.typeinfo.model.TypeInfoModelFactory;
import org.eclipse.dltk.javascript.typeinfo.model.Visibility;
import org.eclipse.emf.common.util.EList;
import org.eclipse.osgi.util.NLS;

/**
 * Implements support for javadocs tags .
 * 
 * @see http://jsdoc.sourceforge.net/
 * @see http://code.google.com/p/jsdoc-toolkit/wiki/TagType
 * @see http://code.google.com/p/jsdoc-toolkit/wiki/TagParam
 */
public class JSDocSupport implements IModelBuilder {

	public static final String PARAM_DOTS = "...";
	public static final String PARAM_OPTIONAL = "=";

	public String getFeatureId() {
		return JSDocSupport.class.getName();
	}

	public int priorityFor(ITypeInfoContext context) {
		return PRIORITY_DEFAULT;
	}

	public static JSDocTags parse(Comment comment) {
		return new SimpleJSDocParser().parse(comment.getText(),
				comment.sourceStart());
	}

	public enum JSDocFunctionContext {
		DECLARATION {
			@Override
			String[] getReturnTags() {
				return JSDocTag.RETURN_TAGS;
			}
		},
		EXPRESSION {
			@Override
			String[] getReturnTags() {
				return RETURN_ONLY_TAGS;
			}
		};

		static final String[] RETURN_ONLY_TAGS = { JSDocTag.RETURNS,
				JSDocTag.RETURN };

		abstract String[] getReturnTags();
	}

	public void processMethod(FunctionStatement statement, IMethod method,
			JSProblemReporter reporter, ITypeChecker typeChecker) {
		Comment comment = getComment(statement);
		if (comment == null) {
			return;
		}
		final JSDocTags tags = parse(comment);
		processMethod(method,
				statement.isDeclaration() ? JSDocFunctionContext.DECLARATION
						: JSDocFunctionContext.EXPRESSION, tags, reporter,
				typeChecker);
	}

	public final void processMethod(IMethod method, final JSDocTags tags,
			JSProblemReporter reporter, ITypeChecker typeChecker) {
		processMethod(method, JSDocFunctionContext.EXPRESSION, tags, reporter,
				typeChecker);
	}

	public void processMethod(IMethod method, JSDocFunctionContext context,
			final JSDocTags tags, JSProblemReporter reporter,
			ITypeChecker typeChecker) {
		if (method.getType() == null) {
			parseType(method, tags, context.getReturnTags(), reporter,
					typeChecker);
		}
		parseParams(method, tags, reporter, typeChecker);
		parseThis(method, tags, reporter, typeChecker);
		parseDeprecation(method, tags, reporter);
		parseAccessModifiers(method, tags, reporter);
		parseConstructor(method, tags, reporter);
		parseExtends(method, tags, reporter, typeChecker);
		parseThrows(method, tags, reporter, typeChecker);
		parseSuppressWarnings(method, tags, reporter);
	}

	private void parseExtends(IMethod method, JSDocTags tags,
			JSProblemReporter reporter, ITypeChecker typeChecker) {
		final JSDocTag extendsTag = tags.get(JSDocTag.EXTENDS);
		if (extendsTag != null) {
			final JSType type = parseType(extendsTag, false, reporter);
			if (type != null) {
				if (typeChecker != null)
					typeChecker.checkType(type, extendsTag);
				method.setExtendsType(type);
			}
			validateSingleTag(tags, JSDocTag.EXTENDS, reporter);
		}
	}

	protected void parseSuppressWarnings(IElement element, JSDocTags tags,
			JSProblemReporter reporter) {
		final List<JSDocTag> suppressWarnings = tags
				.list(JSDocTag.SUPPRESS_WARNINGS);
		if (!suppressWarnings.isEmpty()) {
			for (JSDocTag tag : suppressWarnings) {
				processSuppressWarnings(tag, new CountingReporter(reporter),
						element);
			}
		}
	}

	private void parseThrows(IMethod method, JSDocTags tags,
			JSProblemReporter reporter, ITypeChecker typeChecker) {
		if (typeChecker != null) {
			List<JSDocTag> throwsTags = tags.list(JSDocTag.THROWS);
			for (JSDocTag throwsTag : throwsTags) {
				String value = throwsTag.value();
				String[] split = value.split(" ");
				if (split.length > 0) {
					if (isBraced(split[0])) {
						JSType type = translateTypeName(cutBraces(split[0]),
								throwsTag, reporter);
						typeChecker.checkType(type, throwsTag);
					}
				}
			}
		}

	}

	public static Comment getCallComment(CallExpression call) {
		ASTNode node = call;
		while (node != null) {
			if (node instanceof JSNode) {
				final Comment doc = ((JSNode) node).getDocumentation();
				if (doc != null) {
					return doc;
				}
			}
			if (node instanceof Statement) {
				break;
			}
			if (!(node instanceof JSNode)) {
				break;
			}
			node = ((JSNode) node).getParent();
		}
		return null;
	}

	@Deprecated
	public static Comment getFunctionComment(FunctionStatement statement) {
		return getComment(statement);
	}

	public static Comment getComment(JSNode statement) {
		Comment documentation = statement.getDocumentation();
		if (documentation != null) {
			return documentation;
		}
		final ASTNode parent = statement.getParent();
		if (parent instanceof BinaryOperation) {
			final BinaryOperation binary = (BinaryOperation) parent;
			if (binary.getOperation() == JSParser.ASSIGN
					&& binary.getRightExpression() == statement) {
				documentation = binary.getLeftExpression().getDocumentation();
				if (documentation != null) {
					return documentation;
				}
			}
		} else if (parent instanceof PropertyInitializer) {
			final PropertyInitializer property = (PropertyInitializer) parent;
			if (property.getValue() == statement) {
				documentation = property.getName().getDocumentation();
				if (documentation != null) {
					return documentation;
				}
			}
		} else if (parent instanceof VariableDeclaration) {
			final VariableDeclaration variable = (VariableDeclaration) parent;
			if ((variable.getInitializer() == statement || variable
					.getIdentifier() == statement)
					&& variable.getParent() instanceof VariableStatement) {
				return ((VariableStatement) variable.getParent())
						.getDocumentation();
			}
		} else if (parent instanceof PropertyExpression) {
			return getComment((PropertyExpression) parent);
		}
		return null;
	}

	private void parseConstructor(IMethod method, JSDocTags tags,
			JSProblemReporter reporter) {
		if (tags.get(JSDocTag.CONSTRUCTOR) != null) {
			method.setConstructor(true);
			validateSingleTag(tags, JSDocTag.CONSTRUCTOR, reporter);
		}
	}

	public static class NamedValue<T> {
		public final String name;
		public final T value;

		private NamedValue(String name, T value) {
			this.name = name;
			this.value = value;
		}

		public static <T> NamedValue<T> of(String name, T value) {
			return new NamedValue<T>(name, value);
		}
	}

	protected static final List<NamedValue<Visibility>> STANDARD_ACCESS_MODIFIERS;

	static {
		final List<NamedValue<Visibility>> modifiers = new ArrayList<NamedValue<Visibility>>(
				3);
		modifiers.add(NamedValue.of(JSDocTag.PUBLIC, Visibility.PUBLIC));
		modifiers.add(NamedValue.of(JSDocTag.PROTECTED, Visibility.PROTECTED));
		modifiers.add(NamedValue.of(JSDocTag.PRIVATE, Visibility.PRIVATE));
		STANDARD_ACCESS_MODIFIERS = modifiers;
	}

	protected List<NamedValue<Visibility>> getSupportedAccessModifiers() {
		return STANDARD_ACCESS_MODIFIERS;
	}

	public void parseAccessModifiers(IMember member, JSDocTags tags,
			JSProblemReporter reporter) {
		final List<NamedValue<Visibility>> accessModifiers = getSupportedAccessModifiers();
		for (int i = 0; i < accessModifiers.size(); ++i) {
			final NamedValue<Visibility> pair = accessModifiers.get(i);
			final JSDocTag tag = tags.get(pair.name);
			if (tag != null) {
				member.setVisibility(pair.value);
				int extraTags = tags.count(pair.name) - 1;
				for (int j = i + 1; extraTags == 0
						&& j < accessModifiers.size(); ++j) {
					extraTags += tags.count(accessModifiers.get(j).name);
				}
				if (extraTags > 0) {
					final List<JSDocTag> all = new ArrayList<JSDocTag>();
					all.addAll(tags.list(pair.name));
					all.remove(tag);
					for (int j = i + 1; j < accessModifiers.size(); ++j) {
						all.addAll(tags.list(accessModifiers.get(j).name));
					}
					for (JSDocTag t : all) {
						reportProblem(reporter, JSDocProblem.IGNORED_TAG, t,
								t.name(), tag.name());
					}
				}
				break;
			}
		}
	}

	private void validateSingleTag(JSDocTags tags, String tagName,
			JSProblemReporter reporter) {
		if (reporter != null && tags.count(tagName) > 1) {
			final List<JSDocTag> t = tags.list(tagName);
			for (JSDocTag tag : t.subList(1, t.size())) {
				reportProblem(reporter, JSDocProblem.DUPLICATE_TAG, tag,
						tag.name());
			}
		}
	}

	public void processVariable(VariableDeclaration declaration,
			IVariable variable, JSProblemReporter reporter,
			ITypeChecker typeChecker) {
		Comment comment = declaration.getDocumentation();
		if (comment == null) {
			final IVariableStatement statement = declaration.getStatement();
			final List<VariableDeclaration> vars = statement.getVariables();
			if (!vars.isEmpty() && vars.get(0) == declaration) {
				comment = statement.getDocumentation();
				if (comment == null) {
					return;
				}
			} else {
				return;
			}
		}
		final JSDocTags tags = parse(comment);
		if (variable.getType() == null) {
			parseType(variable, tags, TYPE_TAGS, reporter, typeChecker);
		}
		parseTypeDef(variable, tags, reporter, typeChecker);
		parseDeprecation(variable, tags, reporter);
		parseAccessModifiers(variable, tags, reporter);
		parseSuppressWarnings(variable, tags, reporter);
	}

	private void parseTypeDef(IVariable variable, JSDocTags tags,
			JSProblemReporter reporter, ITypeChecker typeChecker) {
		final JSDocTag typeDefTag = tags.get(JSDocTag.TYPEDEF);
		if (typeDefTag != null) {
			final JSType type = parseType(typeDefTag, false, reporter);
			if (type != null) {
				if (!(type instanceof RecordType)) {
					reportProblem(reporter, JSDocProblem.UNSUPPORTED_TYPEDEF,
							typeDefTag, type.getName());
				} else {
					if (typeChecker != null)
						typeChecker.checkType(type, typeDefTag);
					variable.setTypeDef(type);
				}
			}
			validateSingleTag(tags, JSDocTag.TYPEDEF, reporter);
			if (reporter != null && tags.count(JSDocTag.TYPE) > 0) {
				reportProblem(reporter, JSDocProblem.TYPE_WITH_TYPEDEF,
						typeDefTag, typeDefTag.name());
			}
		}
	}

	private void parseThis(IMethod method, JSDocTags tags,
			JSProblemReporter reporter, ITypeChecker typeChecker) {
		final JSDocTag thisTag = tags.get(JSDocTag.THIS);
		if (thisTag != null) {
			final JSType type = parseType(thisTag, false, reporter);
			if (type != null) {
				if (typeChecker != null)
					typeChecker.checkType(type, thisTag);
				method.setThisType(type);
			}
			validateSingleTag(tags, JSDocTag.THIS, reporter);
		}
	}

	public void parseDeprecation(IMember member, JSDocTags tags,
			JSProblemReporter reporter) {
		if (tags.get(JSDocTag.DEPRECATED) != null) {
			member.setDeprecated(true);
			validateSingleTag(tags, JSDocTag.DEPRECATED, reporter);
		}
	}

	protected static class ParamInfo {
		public String type;
		public boolean varargs;
		public boolean optional;

		void clear() {
			type = null;
			varargs = false;
			optional = false;
		}
	}

	protected void parseParams(IMethod method, JSDocTags tags,
			JSProblemReporter reporter, ITypeChecker typeChecker) {
		final List<JSDocTag> paramTags = tags.list(JSDocTag.PARAM);
		if (paramTags.isEmpty()) {
			return;
		}
		int problemCount = 0;
		final Map<String, RecordType> objectPropertiesTypes = new HashMap<String, RecordType>();
		final Set<String> processedParams = new HashSet<String>();
		final ParamInfo pp = new ParamInfo();
		for (JSDocTag tag : paramTags) {
			pp.clear();
			final TagTokenizer st = new TagTokenizer(tag);
			if (st.hasMoreTokens()) {
				final String token = st.peek();
				if (isBraced(token)) {
					String type = cutBraces(token);
					if (type.startsWith(PARAM_DOTS)) {
						pp.varargs = true;
						type = type.substring(PARAM_DOTS.length());
					} else if (type.endsWith(PARAM_DOTS)) {
						pp.varargs = true;
						type = type.substring(0,
								type.length() - PARAM_DOTS.length());
					} else if (type.endsWith(PARAM_OPTIONAL)) {
						type = type.substring(0,
								type.length() - PARAM_OPTIONAL.length());
						pp.optional = true;
					}
					pp.type = type;
					st.nextToken();
				}
			}
			if (st.hasMoreTokens()) {
				String paramName = st.nextToken();
				if (paramName.startsWith("[") && paramName.endsWith("]")) {
					pp.optional = true;
					paramName = paramName.substring(1, paramName.length() - 1);
					int defaultValueSeperatorIndex = paramName.indexOf('=');
					if (defaultValueSeperatorIndex != -1) {
						paramName = paramName.substring(0,
								defaultValueSeperatorIndex);
					}
				}
				if (!pp.varargs && paramName.endsWith(PARAM_DOTS)) {
					// just in case, so next condition doesn't use ".." as
					// property name.
					pp.varargs = true;
					paramName = paramName.substring(0, paramName.length()
							- PARAM_DOTS.length());
				}
				String propertyName = null;
				int propertiesObjectIndex = paramName.lastIndexOf('.');
				if (propertiesObjectIndex != -1) {
					// http://code.google.com/p/jsdoc-toolkit/wiki/TagParam
					// = Parameters With Properties =
					propertyName = paramName
							.substring(propertiesObjectIndex + 1);
					if (JavaScriptLanguageUtil.isValidIdentifier(propertyName)) {
						String objectName = paramName.substring(0,
								propertiesObjectIndex);
						RecordType propertiesType = objectPropertiesTypes
								.get(objectName);
						if (propertiesType == null) {
							propertiesType = TypeInfoModelFactory.eINSTANCE
									.createRecordType();
							propertiesType.setTypeName('{' + objectName + '}');
							objectPropertiesTypes.put(objectName,
									propertiesType);
							final IParameter param = method
									.getParameter(objectName);
							if (param != null) {
								param.setType(propertiesType);
								if (pp.optional)
									param.setKind(ParameterKind.OPTIONAL);
							} else {
								int index = objectName.lastIndexOf('.');
								if (index == -1) {
									++problemCount;
									reportProblem(reporter,
											JSDocProblem.UNKNOWN_PARAM, tag,
											objectName);
								} else {
									RecordType parentRecordType = objectPropertiesTypes
											.get(objectName.substring(0, index));
									if (parentRecordType != null) {
										String memberName = objectName
												.substring(index + 1);
										EList<Member> members = parentRecordType
												.getMembers();
										for (Member member : members) {
											if (member.getName().equals(
													memberName)) {
												member.setType(propertiesType);
												break;
											}
										}
									}
								}
							}
						}
						final RecordProperty property = TypeInfoModelFactory.eINSTANCE
								.createRecordProperty();
						property.setName(propertyName);
						if (pp.type != null) {
							JSType type = translateTypeName(pp.type, tag,
									reporter);
							if (typeChecker != null)
								typeChecker.checkType(type, tag);
							property.setType(type);
						}
						property.setOptional(pp.optional);
						propertiesType.getMembers().add(property);
						continue;
					}
				}
				if (method.getParameter(paramName) != null
						&& !processedParams.add(paramName)) {
					++problemCount;
					reportProblem(reporter, JSDocProblem.DUPLICATE_PARAM, tag,
							paramName);
					continue;
				}
				IParameter parameter = method.getParameter(paramName);
				if (parameter != null) {
					if (!pp.optional && st.hasMoreTokens()
							&& st.nextToken().equals("optional")) {
						pp.optional = true;
					}
					updateParameter(tag, parameter, pp, reporter, typeChecker);
				} else if (pp.varargs) {
					/*
					 * create virtual parameter for varargs as most of the time
					 * passed values are accessed via "arguments" object and
					 * parameter declaration in code is not required.
					 */
					parameter = method.createParameter();
					parameter.setName(paramName);
					updateParameter(tag, parameter, pp, reporter, typeChecker);
					method.getParameters().add(parameter);
					processedParams.add(paramName);
				} else {
					++problemCount;
					reportProblem(reporter, JSDocProblem.UNKNOWN_PARAM, tag,
							paramName);
				}
			} else {
				++problemCount;
				reportProblem(reporter, JSDocProblem.MISSING_PARAMETER_NAME,
						tag);
			}
		}
		if (problemCount == 0 && reporter != null) {
			for (IParameter parameter : method.getParameters()) {
				if (!processedParams.contains(parameter.getName())
						&& !objectPropertiesTypes.containsKey(parameter
								.getName())) {
					final ReferenceLocation location = parameter.getLocation();
					reporter.reportProblem(
							JSDocProblem.PARAMETER_MISSING_ANNOTATION,
							JSDocProblem.PARAMETER_MISSING_ANNOTATION
									.formatMessage(parameter.getName()),
							location.getNameStart(), location.getNameEnd());
				}
			}
		}
	}

	protected void updateParameter(JSDocTag tag, final IParameter parameter,
			final ParamInfo pp, JSProblemReporter reporter,
			ITypeChecker typeChecker) {
		if (pp.type != null && parameter.getType() == null) {
			JSType type = translateTypeName(pp.type, tag, reporter);
			if (typeChecker != null)
				typeChecker.checkType(type, tag);
			parameter.setType(type);
		}
		if (pp.varargs) {
			parameter.setKind(ParameterKind.VARARGS);
		} else if (pp.optional) {
			parameter.setKind(ParameterKind.OPTIONAL);
		}
	}

	public static final String[] TYPE_TAGS = { JSDocTag.TYPE };

	public static class TagTokenizer {
		private final String content;
		private final int end;
		private int position;
		private int tokenStart;

		public TagTokenizer(JSDocTag tag) {
			this(tag.value());
		}

		public TagTokenizer(String content) {
			this.content = content;
			this.end = content.length();
			this.position = skipDelimiters(0);
		}

		/**
		 * The token loaded by {@link #peek()} if not <code>null</code>.
		 */
		private String current;

		/**
		 * Checks if there are more tokens available from this tokenizer.
		 */
		public boolean hasMoreTokens() {
			return current != null || position < end;
		}

		/**
		 * Returns the first character of the next token without removing it
		 * from this tokenizer or <code>\0</code> if there are no more tokens.
		 */
		public char peekChar() {
			if (current == null) {
				if (position < end) {
					return content.charAt(position);
				} else {
					return '\0';
				}
			} else if (current.length() != 0) {
				return current.charAt(0);
			} else {
				return '\0';
			}
		}

		/**
		 * Returns the next token without removing it from this tokenizer or
		 * <code>null</code> if there are no more tokens.
		 */
		public String peek() {
			if (current == null) {
				if (position < end) {
					current = fetchNextToken();
				} else {
					return null;
				}
			}
			return current;
		}

		/**
		 * Returns the next token from this tokenizer.
		 * 
		 * @throws NoSuchElementException
		 *             if no more tokens available.
		 */
		public String nextToken() {
			if (current != null) {
				final String token = current;
				current = null;
				return token;
			}
			return fetchNextToken();
		}

		/**
		 * Returns the starting position of the last fetched token.
		 */
		public int getTokenStart() {
			return tokenStart;
		}

		private int skipDelimiters(int pos) {
			while (pos < end && Character.isWhitespace(content.charAt(pos))) {
				++pos;
			}
			return pos;
		}

		private String fetchNextToken() {
			if (position == end) {
				throw new NoSuchElementException();
			}
			tokenStart = position;
			int braceCount = 0;
			while (position < end) {
				if (Character.isWhitespace(content.charAt(position))
						&& braceCount == 0) {
					break;
				} else if (content.charAt(position) == '{') {
					++braceCount;
				} else if (content.charAt(position) == '}') {
					--braceCount;
				}
				++position;
			}
			final String token = content.substring(tokenStart, position);
			position = skipDelimiters(position);
			return token;
		}
	}

	/**
	 * @see St
	 * @param context
	 * @param member
	 * @param comment
	 */
	public void parseType(IElement member, JSDocTags tags, String[] tagNames,
			JSProblemReporter reporter, ITypeChecker typeChecker) {
		final JSDocTag tag = tags.get(tagNames);
		if (tag != null) {
			if (reporter != null) {
				final int count = tags.count(tagNames);
				if (count > 1) {
					for (JSDocTag t : tags.list(tagNames).subList(1, count)) {
						if (t.name().equals(tag.name())) {
							reportProblem(reporter, JSDocProblem.DUPLICATE_TAG,
									t, t.name());
						} else {
							reportProblem(
									reporter,
									JSDocProblem.DUPLICATE_TAG,
									JSDocProblem.DUPLICATE_TAG.formatMessage(t
											.name())
											+ " (was "
											+ tag.name()
											+ ")", t);
						}
					}
				}
			}
			final JSType type = parseType(tag, requireBraces(tag.name()),
					reporter);
			if (type != null) {
				if (typeChecker != null)
					typeChecker.checkType(type, tag);
				member.setType(type);
			}
		}
	}

	public JSType parseType(JSDocTag tag, boolean requireBraces,
			JSProblemReporter reporter) {
		final TagTokenizer st = new TagTokenizer(tag);
		if (st.hasMoreTokens()) {
			final String typeName = st.nextToken();
			if (!requireBraces || isBraced(typeName)) {
				return translateTypeName(cutBraces(typeName), tag, reporter);
			}
		} else if (!requireBraces) {
			reportProblem(reporter, JSDocProblem.WRONG_TYPE_SYNTAX,
					"Missing type name", tag);
		}
		return null;
	}

	protected boolean requireBraces(String tagName) {
		return JSDocTag.RETURN.equals(tagName)
				|| JSDocTag.RETURNS.equals(tagName);
	}

	private void reportProblem(JSProblemReporter reporter,
			JSProblemIdentifier problemIdentifier, JSDocTag tag, Object... args) {
		if (reporter != null) {
			reporter.reportProblem(problemIdentifier,
					problemIdentifier.formatMessage(args), tag.start(),
					tag.end());
		}
	}

	private void reportProblem(JSProblemReporter reporter,
			JSProblemIdentifier problemIdentifier, String message, JSDocTag tag) {
		if (reporter != null) {
			reporter.reportProblem(problemIdentifier, message, tag.start(),
					tag.end());
		}
	}

	protected JSType translateTypeName(String typeName, JSDocTag tag,
			JSProblemReporter reporter) {
		JSDocTypeParser parser = createTypeParser();
		try {
			return parser.parse(typeName);
		} catch (JSDocParseException e) {
			if (reporter != null) {
				reporter.reportProblem(e.problemId, e.getMessage(),
						tag.start(), tag.end());
			}
			return null;
		} catch (ParseException e) {
			if (reporter != null) {
				String message = e.getMessage();
				if (e.getErrorOffset() >= 0) {
					message += " after "
							+ typeName.substring(0, e.getErrorOffset());
				}
				reporter.reportProblem(JSDocProblem.WRONG_TYPE_SYNTAX, message,
						tag.start(), tag.end());
			}
			return null;
		}
	}

	public JSDocTypeParser createTypeParser() {
		return new JSDocTypeParser();
	}

	public static String cutBraces(String typeName) {
		if (isBraced(typeName)) {
			typeName = typeName.substring(1, typeName.length() - 1);
		}
		return typeName;
	}

	public static boolean isBraced(String typeName) {
		final int length = typeName.length();
		return length > 2 && typeName.charAt(0) == '{'
				&& typeName.charAt(length - 1) == '}';
	}

	private static class CountingReporter implements ProblemReporter {
		@Nullable
		final JSProblemReporter reporter;
		int problemCount;

		public CountingReporter(@Nullable JSProblemReporter reporter) {
			this.reporter = reporter;
		}

		public void reportProblem(IProblemIdentifier identifier,
				String message, int start, int end) {
			++problemCount;
			if (reporter != null) {
				reporter.reportProblem(identifier, message, start, end);
			}
		}
	}

	private void processSuppressWarnings(JSDocTag tag,
			@NonNull CountingReporter reporter, IElement element) {
		final CharStream input = new ANTLRStringStream(tag.value());
		final boolean hasParenthesis = input.LT(1) == '(';
		if (hasParenthesis) {
			input.consume();
		}
		for (;;) {
			int ch = input.LT(1);
			while (Character.isWhitespace(ch)) {
				input.consume();
				ch = input.LT(1);
			}
			if (ch == '"' || ch == '\'') {
				final char quote = (char) ch;
				input.consume();
				final int start = input.index();
				for (;;) {
					ch = input.LT(1);
					if (ch == quote) {
						suppressWarning(tag, reporter, element, input, start);
						input.consume();
						break;
					} else if (ch == CharStream.EOF) {
						reporter.reportProblem(
								JSDocProblem.WRONG_SUPPRESS_WARNING, "Closing "
										+ quote + " expected", tag.start(),
								tag.end());
						break;
					}
					input.consume();
				}
			} else {
				final int start = input.index();
				for (;;) {
					ch = input.LT(1);
					if (ch == ',' || ch == ')' || ch == CharStream.EOF
							|| Character.isWhitespace(ch)) {
						suppressWarning(tag, reporter, element, input, start);
						break;
					}
					input.consume();
				}
			}
			ch = input.LT(1);
			while (ch != CharStream.EOF && Character.isWhitespace(ch)) {
				input.consume();
				ch = input.LT(1);
			}
			if (ch != ',') {
				break;
			}
			input.consume();
		}
		if (hasParenthesis) {
			if (input.LT(1) == ')') {
				input.consume();
			} else {
				reporter.reportProblem(JSDocProblem.WRONG_SUPPRESS_WARNING,
						"Closing ) expected", tag.start(), tag.end());
			}
		}
		if (reporter.problemCount != 0 && input.LT(1) != CharStream.EOF) {
			reporter.reportProblem(JSDocProblem.WRONG_SUPPRESS_WARNING,
					"Unexpected content", tag.start(), tag.end());
		}
	}

	private void suppressWarning(JSDocTag tag,
			@NonNull CountingReporter reporter, IElement element,
			final CharStream input, final int start) {
		final String categoryId = input.substring(start, input.index() - 1);
		if (categoryId.length() != 0) {
			final IProblemCategory category = getCategory(categoryId);
			if (category != null) {
				element.addSuppressedWarning(category);
			} else {
				reporter.reportProblem(JSDocProblem.WRONG_SUPPRESS_WARNING, NLS
						.bind("Unsupported {0}({1})",
								JSDocTag.SUPPRESS_WARNINGS, categoryId), tag
						.start(), tag.end());
			}
		} else {
			reporter.reportProblem(JSDocProblem.WRONG_SUPPRESS_WARNING,
					"warning identifier expected", tag.start(), tag.end());
		}
	}

	protected IProblemCategory getCategory(final String categoryId) {
		return ProblemCategoryManager.getInstance().getCategory(
				JavaScriptNature.NATURE_ID, JSDocTag.SUPPRESS_WARNINGS,
				categoryId);
	}

	/**
	 * Value type for the results of the high-level JSDoc tag parsing.
	 * 
	 * @see JSDocSupport#parseParameter(JSDocTag)
	 * @see JSDocSupport#parseOptionalType(JSDocTag)
	 * @see JSDocSupport#parseType(JSDocTag)
	 */
	public static class TypedElementNode {
		/**
		 * Type expression, potentially with surrounding braces or
		 * <code>null</code>
		 */
		@Nullable
		private final String type;
		/**
		 * Offset of the type token or <code>-1</code> if no type
		 */
		private final int typeOffset;

		/**
		 * Answers if type expression is surrounded with braces.
		 */
		boolean isBraced() {
			return true;
		}

		TypedElementNode(String type, int typeOffset) {
			this.type = type;
			this.typeOffset = typeOffset;
		}

		/**
		 * Returns type expression without surrounding braces or
		 * <code>null</code>
		 */
		@Nullable
		public String getTypeExpression() {
			if (type != null) {
				return isBraced() ? type.substring(1, type.length() - 1) : type;
			} else {
				return null;
			}
		}

		/**
		 * Returns the starting offset of the actual type expression (i.e.
		 * without surrounding braces) or <code>-1</code> if no type expression.
		 */
		public int getTypeExpressionStart() {
			return typeOffset >= 0 ? typeOffset + (isBraced() ? 1 : 0) : -1;
		}

		/**
		 * Checks if specified position is contained in the type declaration.
		 */
		public boolean isInType(int position) {
			return type != null
					&& (isBraced() ? typeOffset < position
							&& position < typeOffset + type.length()
							: typeOffset <= position
									&& position <= typeOffset + type.length());
		}
	}

	public static class ParameterNode extends TypedElementNode {
		@NonNull
		public final String name;
		public final int offset;

		ParameterNode(String type, int typeOffset, String name, int offset) {
			super(type, typeOffset);
			this.name = name;
			this.offset = offset;
		}

		public boolean isInParameter(int position) {
			return offset <= position && offset + name.length() >= position;
		}
	}

	public static class TypeNode extends TypedElementNode {
		private final boolean braced;

		@Override
		boolean isBraced() {
			return braced;
		}

		TypeNode(String type, int typeOffset, boolean braced) {
			super(type, typeOffset);
			this.braced = braced;
		}
	}

	/**
	 * High level parsing of JSDoc &#64;param tag
	 */
	public static ParameterNode parseParameter(JSDocTag tag) {
		final TagTokenizer tokenizer = new TagTokenizer(tag);
		if (!tokenizer.hasMoreTokens()) {
			return null;
		}
		int typeOffset = -1;
		String type = null;
		String token = tokenizer.nextToken();
		if (JSDocSupport.isBraced(token)) { // skip type name
			if (!tokenizer.hasMoreTokens()) {
				return null;
			}
			typeOffset = tokenizer.getTokenStart();
			type = token;
			token = tokenizer.nextToken();
		}
		int tokenStart = tokenizer.getTokenStart();
		// optional parameter
		if (token.startsWith("[") && token.endsWith("]")) {
			token = token.substring(1, token.length() - 1);
			++tokenStart;
			// default value separator
			int separator = token.indexOf('=');
			if (separator != -1) {
				token = token.substring(0, separator);
			}
		}
		int propertyIndex = token.indexOf('.');
		if (propertyIndex != -1) {
			token = token.substring(0, propertyIndex);
		}
		return new ParameterNode(type, typeOffset, token, tokenStart);
	}

	/**
	 * Parses optional type expression (like the one in &#64;return/&#64;returns
	 * tags) from the specified tag value.
	 */
	public static TypedElementNode parseOptionalType(JSDocTag tag) {
		final TagTokenizer tokenizer = new TagTokenizer(tag);
		if (tokenizer.peekChar() == '{' && tokenizer.hasMoreTokens()) {
			final String type = tokenizer.nextToken();
			return new TypedElementNode(type, tokenizer.getTokenStart());
		} else {
			return null;
		}
	}

	/**
	 * Parses the type expression of &#64;type tag.
	 */
	public static TypeNode parseType(JSDocTag tag) {
		final TagTokenizer tokenizer = new TagTokenizer(tag);
		if (tokenizer.hasMoreTokens()) {
			final String type = tokenizer.nextToken();
			return new TypeNode(type, tokenizer.getTokenStart(), isBraced(type));
		} else {
			return null;
		}
	}

}
