/*******************************************************************************
 * Copyright (c) 2000, 2003 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials 
 * are made available under the terms of the Common Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/cpl-v10.html
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/

package org.eclipse.jdt.core.dom;

import org.eclipse.jdt.internal.compiler.Compiler;
import org.eclipse.jdt.internal.compiler.*;
import org.eclipse.jdt.internal.compiler.env.*;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.*;
import org.eclipse.jdt.core.compiler.*;
import org.eclipse.jdt.internal.core.*;
import org.eclipse.jdt.internal.compiler.impl.*;
import org.eclipse.jdt.internal.compiler.ast.*;
import org.eclipse.jdt.internal.compiler.lookup.PackageBinding;
import org.eclipse.jdt.internal.compiler.parser.Parser;
import org.eclipse.jdt.internal.compiler.parser.SourceTypeConverter;
import org.eclipse.jdt.internal.compiler.problem.*;

import java.util.*;

class CompilationUnitResolver extends Compiler {
	
	/**
	 * Answer a new CompilationUnitVisitor using the given name environment and compiler options.
	 * The environment and options will be in effect for the lifetime of the compiler.
	 * When the compiler is run, compilation results are sent to the given requestor.
	 *
	 *  @param environment org.eclipse.jdt.internal.compiler.api.env.INameEnvironment
	 *      Environment used by the compiler in order to resolve type and package
	 *      names. The name environment implements the actual connection of the compiler
	 *      to the outside world (for example, in batch mode the name environment is performing
	 *      pure file accesses, reuse previous build state or connection to repositories).
	 *      Note: the name environment is responsible for implementing the actual classpath
	 *            rules.
	 *
	 *  @param policy org.eclipse.jdt.internal.compiler.api.problem.IErrorHandlingPolicy
	 *      Configurable part for problem handling, allowing the compiler client to
	 *      specify the rules for handling problems (stop on first error or accumulate
	 *      them all) and at the same time perform some actions such as opening a dialog
	 *      in UI when compiling interactively.
	 *      @see org.eclipse.jdt.internal.compiler.api.problem.DefaultErrorHandlingPolicies
	 * 
	 *	@param settings The settings to use for the resolution.
	 *      
	 *  @param requestor org.eclipse.jdt.internal.compiler.api.ICompilerRequestor
	 *      Component which will receive and persist all compilation results and is intended
	 *      to consume them as they are produced. Typically, in a batch compiler, it is 
	 *      responsible for writing out the actual .class files to the file system.
	 *      @see org.eclipse.jdt.internal.compiler.api.CompilationResult
	 *
	 *  @param problemFactory org.eclipse.jdt.internal.compiler.api.problem.IProblemFactory
	 *      Factory used inside the compiler to create problem descriptors. It allows the
	 *      compiler client to supply its own representation of compilation problems in
	 *      order to avoid object conversions. Note that the factory is not supposed
	 *      to accumulate the created problems, the compiler will gather them all and hand
	 *      them back as part of the compilation unit result.
	 */
	public CompilationUnitResolver(
		INameEnvironment environment,
		IErrorHandlingPolicy policy,
		Map settings,
		ICompilerRequestor requestor,
		IProblemFactory problemFactory) {

		super(environment, policy, settings, requestor, problemFactory, false);
	}
	
	/**
	 * Add additional source types
	 */
	public void accept(ISourceType[] sourceTypes, PackageBinding packageBinding) {
		CompilationResult result =
			new CompilationResult(sourceTypes[0].getFileName(), 1, 1, this.options.maxProblemsPerUnit);
		// need to hold onto this
		CompilationUnitDeclaration unit =
			SourceTypeConverter.buildCompilationUnit(
				sourceTypes,//sourceTypes[0] is always toplevel here
				true, // need field and methods
				true, // need member types
				false, // no need for field initialization
				lookupEnvironment.problemReporter,
				result);

		if (unit != null) {
			this.lookupEnvironment.buildTypeBindings(unit);
			this.lookupEnvironment.completeTypeBindings(unit, true);
		}
	}

	private static Parser createDomParser(ProblemReporter problemReporter) {
		
		return new Parser(problemReporter, false) {
			// old annotation style check which doesn't include all leading comments into declaration
			// for backward compatibility with 2.1 DOM 
			public void checkAnnotation() {

				if (this.currentElement != null && this.scanner.commentPtr >= 0) {
					flushAnnotationsDefinedPriorTo(endStatementPosition); // discard obsolete comments
				}
				boolean deprecated = false;
				boolean checkDeprecated = false;
				int lastAnnotationIndex = -1;
			
				//since jdk1.2 look only in the last java doc comment...
				nextComment : for (lastAnnotationIndex = scanner.commentPtr; lastAnnotationIndex >= 0; lastAnnotationIndex--){
					//look for @deprecated into the first javadoc comment preceeding the declaration
					int commentSourceStart = scanner.commentStarts[lastAnnotationIndex];
					// javadoc only (non javadoc comment have negative end positions.)
					if (modifiersSourceStart != -1 && modifiersSourceStart < commentSourceStart) {
						continue nextComment;
					}
					if (scanner.commentStops[lastAnnotationIndex] < 0) {
						continue nextComment;
					}
					checkDeprecated = true;
					int commentSourceEnd = scanner.commentStops[lastAnnotationIndex] - 1; //stop is one over
					char[] comment = scanner.source;
			
					deprecated =
						checkDeprecation(
							commentSourceStart,
							commentSourceEnd,
							comment);
					break nextComment;
				}
				if (deprecated) {
					checkAndSetModifiers(AccDeprecated);
				}
				// modify the modifier source start to point at the first comment
				if (lastAnnotationIndex >= 0 && checkDeprecated) {
					modifiersSourceStart = scanner.commentStarts[lastAnnotationIndex]; 
				}

			}
		};
	}

	/*
	 *  Low-level API performing the actual compilation
	 */
	protected static IErrorHandlingPolicy getHandlingPolicy() {

		// passes the initial set of files to the batch oracle (to avoid finding more than once the same units when case insensitive match)	
		return new IErrorHandlingPolicy() {
			public boolean stopOnFirstError() {
				return false;
			}
			public boolean proceedOnErrors() {
				return false; // stop if there are some errors 
			}
		};
	}

	protected static INameEnvironment getNameEnvironment(ICompilationUnit sourceUnit)
		throws JavaModelException {
		return (SearchableEnvironment) ((JavaProject) sourceUnit.getJavaProject())
			.getSearchableNameEnvironment();
	}

	protected static INameEnvironment getNameEnvironment(IJavaProject javaProject)
		throws JavaModelException {
		return (SearchableEnvironment) ((JavaProject) javaProject)
			.getSearchableNameEnvironment();
	}
	
	/*
	 * Answer the component to which will be handed back compilation results from the compiler
	 */
	protected static ICompilerRequestor getRequestor() {
		return new ICompilerRequestor() {
			public void acceptResult(CompilationResult compilationResult) {
			}
		};
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jdt.internal.compiler.Compiler#initializeParser()
	 */
	public void initializeParser() {
		// TODO Auto-generated method stub
		this.parser = createDomParser(this.problemReporter);
	}
	public static CompilationUnitDeclaration resolve(
		ICompilationUnit unitElement)
		throws JavaModelException {

		char[] fileName = unitElement.getElementName().toCharArray();
		IJavaProject project = unitElement.getJavaProject();
		CompilationUnitResolver compilationUnitVisitor =
			new CompilationUnitResolver(
				getNameEnvironment(unitElement),
				getHandlingPolicy(),
				project.getOptions(true),
				getRequestor(),
				new DefaultProblemFactory());

		CompilationUnitDeclaration unit = null;
		try {
			String encoding = project.getOption(JavaCore.CORE_ENCODING, true);

			IPackageFragment packageFragment = (IPackageFragment)unitElement.getAncestor(IJavaElement.PACKAGE_FRAGMENT);
			char[][] expectedPackageName = null;
			if (packageFragment != null){
				expectedPackageName = CharOperation.splitOn('.', packageFragment.getElementName().toCharArray());
			}
			
			unit =
				compilationUnitVisitor.resolve(
					new BasicCompilationUnit(
						unitElement.getSource().toCharArray(),
						expectedPackageName,
						new String(fileName),
						encoding),
					true, // method verification
					true, // analyze code
					true); // generate code
			return unit;
		} finally {
			if (unit != null) {
				unit.cleanUp();
			}
		}
	}
	
	public static CompilationUnitDeclaration parse(char[] source, Map settings) {
		if (source == null) {
			throw new IllegalArgumentException();
		}
		CompilerOptions compilerOptions = new CompilerOptions(settings);
		Parser parser = createDomParser(
			new ProblemReporter(
					DefaultErrorHandlingPolicies.proceedWithAllProblems(), 
					compilerOptions, 
					new DefaultProblemFactory()));
		org.eclipse.jdt.internal.compiler.env.ICompilationUnit sourceUnit = 
			new org.eclipse.jdt.internal.compiler.batch.CompilationUnit(
				source, 
				"", //$NON-NLS-1$
				compilerOptions.defaultEncoding);
		CompilationUnitDeclaration compilationUnitDeclaration = parser.dietParse(sourceUnit, new CompilationResult(sourceUnit, 0, 0, compilerOptions.maxProblemsPerUnit));
		
		if (compilationUnitDeclaration.ignoreMethodBodies) {
			compilationUnitDeclaration.ignoreFurtherInvestigation = true;
			// if initial diet parse did not work, no need to dig into method bodies.
			return compilationUnitDeclaration; 
		}
		
		//fill the methods bodies in order for the code to be generated
		//real parse of the method....
		parser.scanner.setSource(source);
		org.eclipse.jdt.internal.compiler.ast.TypeDeclaration[] types = compilationUnitDeclaration.types;
		if (types != null) {
			for (int i = types.length; --i >= 0;)
				types[i].parseMethod(parser, compilationUnitDeclaration);
		}
		return compilationUnitDeclaration;
	}

	public static CompilationUnitDeclaration parse(char[] source, NodeSearcher nodeSearcher, Map settings) {
		if (source == null) {
			throw new IllegalArgumentException();
		}
		CompilerOptions compilerOptions = new CompilerOptions(settings);
		Parser parser = createDomParser(
			new ProblemReporter(
					DefaultErrorHandlingPolicies.proceedWithAllProblems(), 
					compilerOptions, 
					new DefaultProblemFactory()));
		org.eclipse.jdt.internal.compiler.env.ICompilationUnit sourceUnit = 
			new org.eclipse.jdt.internal.compiler.batch.CompilationUnit(
				source, 
				"", //$NON-NLS-1$
				compilerOptions.defaultEncoding);
		CompilationUnitDeclaration compilationUnitDeclaration = parser.dietParse(sourceUnit, new CompilationResult(sourceUnit, 0, 0, compilerOptions.maxProblemsPerUnit));
		
		if (compilationUnitDeclaration.ignoreMethodBodies) {
			compilationUnitDeclaration.ignoreFurtherInvestigation = true;
			// if initial diet parse did not work, no need to dig into method bodies.
			return null; 
		}
				
		compilationUnitDeclaration.traverse(nodeSearcher, compilationUnitDeclaration.scope);
		
		AstNode node = nodeSearcher.found;
 		if (node == null) {
 			return compilationUnitDeclaration;
 		}
 		
 		org.eclipse.jdt.internal.compiler.ast.TypeDeclaration enclosingTypeDeclaration = nodeSearcher.enclosingType;
 		
		if (node instanceof AbstractMethodDeclaration) {
			((AbstractMethodDeclaration)node).parseStatements(parser, compilationUnitDeclaration);
		} else if (enclosingTypeDeclaration != null) {
			if (node instanceof org.eclipse.jdt.internal.compiler.ast.Initializer) {
				((org.eclipse.jdt.internal.compiler.ast.Initializer) node).parseStatements(parser, enclosingTypeDeclaration, compilationUnitDeclaration);
			} else {  					
				((org.eclipse.jdt.internal.compiler.ast.TypeDeclaration)node).parseMethod(parser, compilationUnitDeclaration);
			} 				
		}
		
		return compilationUnitDeclaration;
	}

	public static CompilationUnitDeclaration resolve(
		char[] source,
		String unitName,
		IJavaProject javaProject)
		throws JavaModelException {
	
		CompilationUnitResolver compilationUnitVisitor =
			new CompilationUnitResolver(
				getNameEnvironment(javaProject),
				getHandlingPolicy(),
				javaProject.getOptions(true),
				getRequestor(),
				new DefaultProblemFactory());
	
		CompilationUnitDeclaration unit = null;
		try {
			String encoding = javaProject.getOption(JavaCore.CORE_ENCODING, true);

			unit =
				compilationUnitVisitor.resolve(
					new BasicCompilationUnit(
						source,
						null,
						unitName,
						encoding),
					true, // method verification
					true, // analyze code
					true); // generate code
			return unit;
		} finally {
			if (unit != null) {
				unit.cleanUp();
			}
		}
	}

	public static CompilationUnitDeclaration resolve(
		ICompilationUnit unitElement,
		NodeSearcher nodeSearcher)
		throws JavaModelException {

		CompilationUnitDeclaration unit = null;
		try {
			char[] fileName = unitElement.getElementName().toCharArray();
			IJavaProject project = unitElement.getJavaProject();
			CompilationUnitResolver compilationUnitVisitor =
				new CompilationUnitResolver(
					getNameEnvironment(unitElement),
					getHandlingPolicy(),
					project.getOptions(true),
					getRequestor(),
					new DefaultProblemFactory());
	
			String encoding = project.getOption(JavaCore.CORE_ENCODING, true);
	
			IPackageFragment packageFragment = (IPackageFragment)unitElement.getAncestor(IJavaElement.PACKAGE_FRAGMENT);
			char[][] expectedPackageName = null;
			if (packageFragment != null){
				expectedPackageName = CharOperation.splitOn('.', packageFragment.getElementName().toCharArray());
			}
		
			unit = compilationUnitVisitor.resolve(
				new BasicCompilationUnit(
					unitElement.getSource().toCharArray(),
					expectedPackageName,
					new String(fileName),
					encoding),
				nodeSearcher,
				true, // method verification
				true, // analyze code
				true); // generate code
			return unit;
		} finally {
			if (unit != null) {
				unit.cleanUp();
			}
		}
	}

	public static CompilationUnitDeclaration resolve(
		char[] source,
		char[][] packageName,
		String unitName,
		IJavaProject javaProject)
		throws JavaModelException {
	
		CompilationUnitResolver compilationUnitVisitor =
			new CompilationUnitResolver(
				getNameEnvironment(javaProject),
				getHandlingPolicy(),
				javaProject.getOptions(true),
				getRequestor(),
				new DefaultProblemFactory());
	
		CompilationUnitDeclaration unit = null;
		try {
			String encoding = javaProject.getOption(JavaCore.CORE_ENCODING, true);

			unit =
				compilationUnitVisitor.resolve(
					new BasicCompilationUnit(
						source,
						packageName,
						unitName,
						encoding),
					true, // method verification
					true, // analyze code
					true); // generate code					
			return unit;
		} finally {
			if (unit != null) {
				unit.cleanUp();
			}
		}
	}

	/**
	 * Internal API used to resolve a given compilation unit. Can run a subset of the compilation process
	 */
	public CompilationUnitDeclaration resolve(
			org.eclipse.jdt.internal.compiler.env.ICompilationUnit compilationUnit,
			NodeSearcher nodeSearcher,
			boolean verifyMethods,
			boolean analyzeCode,
			boolean generateCode) {

		CompilationUnitDeclaration unit = null;
		try {

			parseThreshold = 0; // will request a diet parse
			beginToCompile(new org.eclipse.jdt.internal.compiler.env.ICompilationUnit[] { compilationUnit});
			// process all units (some more could be injected in the loop by the lookup environment)
			unit = unitsToProcess[0];
		
			unit.traverse(nodeSearcher, unit.scope);
			
			AstNode node = nodeSearcher.found;
			
 			if (node != null) {
				org.eclipse.jdt.internal.compiler.ast.TypeDeclaration enclosingTypeDeclaration = nodeSearcher.enclosingType;
  				if (node instanceof AbstractMethodDeclaration) {
					((AbstractMethodDeclaration)node).parseStatements(parser, unit);
 				} else if (enclosingTypeDeclaration != null) {
					if (node instanceof org.eclipse.jdt.internal.compiler.ast.Initializer) {
	 					((org.eclipse.jdt.internal.compiler.ast.Initializer) node).parseStatements(parser, enclosingTypeDeclaration, unit);
 					} else if (node instanceof org.eclipse.jdt.internal.compiler.ast.TypeDeclaration) {  					
						((org.eclipse.jdt.internal.compiler.ast.TypeDeclaration)node).parseMethod(parser, unit);
					} 				
 				}
 			}
			if (unit.scope != null) {
				// fault in fields & methods
				unit.scope.faultInTypes();
				if (unit.scope != null && verifyMethods) {
					// http://dev.eclipse.org/bugs/show_bug.cgi?id=23117
 					// verify inherited methods
					unit.scope.verifyMethods(lookupEnvironment.methodVerifier());
				}
				// type checking
				unit.resolve();		

				// flow analysis
				if (analyzeCode) unit.analyseCode();
		
				// code generation
				if (generateCode) unit.generateCode();
			}
			if (unitsToProcess != null) unitsToProcess[0] = null; // release reference to processed unit declaration
			requestor.acceptResult(unit.compilationResult.tagAsAccepted());
			return unit;
		} catch (AbortCompilation e) {
			this.handleInternalException(e, unit);
			return null;
		} catch (Error e) {
			this.handleInternalException(e, unit, null);
			throw e; // rethrow
		} catch (RuntimeException e) {
			this.handleInternalException(e, unit, null);
			throw e; // rethrow
		} finally {
			// No reset is performed there anymore since,
			// within the CodeAssist (or related tools),
			// the compiler may be called *after* a call
			// to this resolve(...) method. And such a call
			// needs to have a compiler with a non-empty
			// environment.
			// this.reset();
		}
	}	
}
