/*******************************************************************************
 * Copyright (c) 2000, 2019 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *     Stephan Herrmann  - Contribution for bug 295551
 *     Jesper S Moller   - Contributions for
 *							  Bug 405066 - [1.8][compiler][codegen] Implement code generation infrastructure for JSR335
 *     Frits Jalvingh    - contributions for bug 533830.
 *     Red Hat Inc.	     - add module-info Javadoc support
 *******************************************************************************/
package org.eclipse.jdt.internal.compiler.ast;

import java.util.Arrays;
import java.util.Comparator;

import org.eclipse.jdt.core.compiler.CategorizedProblem;
import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.core.compiler.IProblem;
import org.eclipse.jdt.internal.compiler.ASTVisitor;
import org.eclipse.jdt.internal.compiler.ClassFile;
import org.eclipse.jdt.internal.compiler.CompilationResult;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
import org.eclipse.jdt.internal.compiler.env.ICompilationUnit;
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
import org.eclipse.jdt.internal.compiler.impl.Constant;
import org.eclipse.jdt.internal.compiler.impl.IrritantSet;
import org.eclipse.jdt.internal.compiler.impl.ReferenceContext;
import org.eclipse.jdt.internal.compiler.lookup.CompilationUnitScope;
import org.eclipse.jdt.internal.compiler.lookup.ImportBinding;
import org.eclipse.jdt.internal.compiler.lookup.LocalTypeBinding;
import org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment;
import org.eclipse.jdt.internal.compiler.lookup.MethodScope;
import org.eclipse.jdt.internal.compiler.lookup.ModuleBinding;
import org.eclipse.jdt.internal.compiler.lookup.Scope;
import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
import org.eclipse.jdt.internal.compiler.parser.NLSTag;
import org.eclipse.jdt.internal.compiler.problem.AbortCompilationUnit;
import org.eclipse.jdt.internal.compiler.problem.AbortMethod;
import org.eclipse.jdt.internal.compiler.problem.AbortType;
import org.eclipse.jdt.internal.compiler.problem.DefaultProblem;
import org.eclipse.jdt.internal.compiler.problem.ProblemReporter;
import org.eclipse.jdt.internal.compiler.problem.ProblemSeverities;
import org.eclipse.jdt.internal.compiler.util.HashSetOfInt;

@SuppressWarnings({ "rawtypes", "unchecked" })
public class CompilationUnitDeclaration extends ASTNode implements ProblemSeverities, ReferenceContext {

	private static final Comparator STRING_LITERAL_COMPARATOR = new Comparator() {
		@Override
		public int compare(Object o1, Object o2) {
			StringLiteral literal1 = (StringLiteral) o1;
			StringLiteral literal2 = (StringLiteral) o2;
			return literal1.sourceStart - literal2.sourceStart;
		}
	};
	private static final int STRING_LITERALS_INCREMENT = 10;

	public ImportReference currentPackage;
	public ImportReference[] imports;
	public TypeDeclaration[] types;
	public ModuleDeclaration moduleDeclaration;
	public int[][] comments;

	public boolean ignoreFurtherInvestigation = false; // once pointless to investigate due to errors
	public boolean ignoreMethodBodies = false;
	public CompilationUnitScope scope;
	public ProblemReporter problemReporter;
	public CompilationResult compilationResult;

	public LocalTypeBinding[] localTypes;
	public int localTypeCount = 0;

	public boolean isPropagatingInnerClassEmulation;

	public Javadoc javadoc; // 1.5 addition for package-info.java

	public NLSTag[] nlsTags;
	private StringLiteral[] stringLiterals;
	private int stringLiteralsPtr;
	private HashSetOfInt stringLiteralsStart;

	public boolean[] validIdentityComparisonLines;

	IrritantSet[] suppressWarningIrritants;  // irritant for suppressed warnings
	Annotation[] suppressWarningAnnotations;
	long[] suppressWarningScopePositions; // (start << 32) + end
	int suppressWarningsCount;
	public int functionalExpressionsCount;
	public FunctionalExpression[] functionalExpressions;

public CompilationUnitDeclaration(ProblemReporter problemReporter, CompilationResult compilationResult, int sourceLength) {
	this.problemReporter = problemReporter;
	this.compilationResult = compilationResult;
	//by definition of a compilation unit....
	this.sourceStart = 0;
	this.sourceEnd = sourceLength - 1;
}

/*
 *	We cause the compilation task to abort to a given extent.
 */
@Override
public void abort(int abortLevel, CategorizedProblem problem) {
	switch (abortLevel) {
		case AbortType :
			throw new AbortType(this.compilationResult, problem);
		case AbortMethod :
			throw new AbortMethod(this.compilationResult, problem);
		default :
			throw new AbortCompilationUnit(this.compilationResult, problem);
	}
}

/*
 * Dispatch code analysis AND request saturation of inner emulation
 */
public void analyseCode() {
	if (this.ignoreFurtherInvestigation)
		return;
	try {
		if (this.types != null) {
			for (int i = 0, count = this.types.length; i < count; i++) {
				this.types[i].analyseCode(this.scope);
			}
		}
		if (this.moduleDeclaration != null) {
			this.moduleDeclaration.analyseCode(this.scope);
		}
		// request inner emulation propagation
		propagateInnerEmulationForAllLocalTypes();
	} catch (AbortCompilationUnit e) {
		this.ignoreFurtherInvestigation = true;
		return;
	}
}

/*
 * When unit result is about to be accepted, removed back pointers
 * to compiler structures.
 */
public void cleanUp() {
	if (this.types != null) {
		for (int i = 0, max = this.types.length; i < max; i++) {
			cleanUp(this.types[i]);
		}
		for (int i = 0, max = this.localTypeCount; i < max; i++) {
		    LocalTypeBinding localType = this.localTypes[i];
			// null out the type's scope backpointers
			localType.cleanUp(); // local members are already in the list
			localType.enclosingCase = null;
		}
	}
	if (this.functionalExpressionsCount > 0) {
		for (int i = 0, max = this.functionalExpressionsCount; i < max; i++) {
			this.functionalExpressions[i].cleanUp();
		}
	}

	this.compilationResult.recoveryScannerData = null; // recovery is already done

	ClassFile[] classFiles = this.compilationResult.getClassFiles();
	for (int i = 0, max = classFiles.length; i < max; i++) {
		// clear the classFile back pointer to the bindings
		ClassFile classFile = classFiles[i];
		// null out the classfile backpointer to a type binding
		classFile.referenceBinding = null;
		classFile.innerClassesBindings = null;
		classFile.bootstrapMethods = null;
		classFile.missingTypes = null;
		classFile.visitedTypes = null;
	}

	this.suppressWarningAnnotations = null;

	if (this.scope != null)
		this.scope.cleanUpInferenceContexts();
}

private void cleanUp(TypeDeclaration type) {
	if (type.memberTypes != null) {
		for (int i = 0, max = type.memberTypes.length; i < max; i++){
			cleanUp(type.memberTypes[i]);
		}
	}
	if (type.binding != null && type.binding.isAnnotationType())
		this.compilationResult.hasAnnotations = true;
	if (type.binding != null) {
		// null out the type's scope backpointers
		type.binding.cleanUp();
	}
}

public void checkUnusedImports(){
	if (this.scope.imports != null){
		for (int i = 0, max = this.scope.imports.length; i < max; i++){
			ImportBinding importBinding = this.scope.imports[i];
			ImportReference importReference = importBinding.reference;
			if (importReference != null && ((importReference.bits & ASTNode.Used) == 0)){
				this.scope.problemReporter().unusedImport(importReference);
			}
		}
	}
}

@Override
public CompilationResult compilationResult() {
	return this.compilationResult;
}

public void createPackageInfoType() {
	TypeDeclaration declaration = new TypeDeclaration(this.compilationResult);
	declaration.name = TypeConstants.PACKAGE_INFO_NAME;
	declaration.modifiers = ClassFileConstants.AccDefault | ClassFileConstants.AccInterface;
	declaration.javadoc = this.javadoc;
	this.types[0] = declaration; // Assumes the first slot is meant for this type
}

/*
 * Finds the matching type amoung this compilation unit types.
 * Returns null if no type with this name is found.
 * The type name is a compound name
 * e.g. if we're looking for X.A.B then a type name would be {X, A, B}
 */
public TypeDeclaration declarationOfType(char[][] typeName) {
	for (int i = 0; i < this.types.length; i++) {
		TypeDeclaration typeDecl = this.types[i].declarationOfType(typeName);
		if (typeDecl != null) {
			return typeDecl;
		}
	}
	return null;
}

public void finalizeProblems() {
	int problemCount = this.compilationResult.problemCount;
	CategorizedProblem[] problems = this.compilationResult.problems;
	if (this.suppressWarningsCount == 0) {
		return;
	}
	int removed = 0;
	IrritantSet[] foundIrritants = new IrritantSet[this.suppressWarningsCount];
	CompilerOptions options = this.scope.compilerOptions();
	boolean hasMandatoryErrors = false;
	nextProblem: for (int iProblem = 0, length = problemCount; iProblem < length; iProblem++) {
		CategorizedProblem problem = problems[iProblem];
		int problemID = problem.getID();
		int irritant = ProblemReporter.getIrritant(problemID);
		boolean isError = problem.isError();
		if (isError) {
			if (irritant == 0) {
				// tolerate unused warning tokens when mandatory errors
				hasMandatoryErrors = true;
				continue;
			}
			if (!options.suppressOptionalErrors) {
				continue;
			}
		}
		int start = problem.getSourceStart();
		int end = problem.getSourceEnd();
		nextSuppress: for (int iSuppress = 0, suppressCount = this.suppressWarningsCount; iSuppress < suppressCount; iSuppress++) {
			long position = this.suppressWarningScopePositions[iSuppress];
			int startSuppress = (int) (position >>> 32);
			int endSuppress = (int) position;
			if (start < startSuppress) continue nextSuppress;
			if (end > endSuppress) continue nextSuppress;
			if (!this.suppressWarningIrritants[iSuppress].isSet(irritant)) {
				if (problem instanceof DefaultProblem) {
					((DefaultProblem) problem).reportError();
				}
				continue nextSuppress;
			}
			// discard suppressed warning
			removed++;
			problems[iProblem] = null;
			this.compilationResult.removeProblem(problem);
			if (foundIrritants[iSuppress] == null){
				foundIrritants[iSuppress] = new IrritantSet(irritant);
			} else {
				foundIrritants[iSuppress].set(irritant);
			}
			continue nextProblem;
		}
	}
	// compact remaining problems
	if (removed > 0) {
		for (int i = 0, index = 0; i < problemCount; i++) {
			CategorizedProblem problem;
			if ((problem = problems[i]) != null) {
				if (i > index) {
					problems[index++] = problem;
				} else {
					index++;
				}
			}
		}
	}
	// flag SuppressWarnings which had no effect (only if no (mandatory) error got detected within unit
	if (!hasMandatoryErrors) {
		int severity = options.getSeverity(CompilerOptions.UnusedWarningToken);
		if (severity != ProblemSeverities.Ignore) {
			boolean unusedWarningTokenIsWarning = (severity & ProblemSeverities.Error) == 0;
			for (int iSuppress = 0, suppressCount = this.suppressWarningsCount; iSuppress < suppressCount; iSuppress++) {
				Annotation annotation = this.suppressWarningAnnotations[iSuppress];
				if (annotation == null) continue; // implicit annotation
				IrritantSet irritants = this.suppressWarningIrritants[iSuppress];
				if (unusedWarningTokenIsWarning && irritants.areAllSet()) continue; // @SuppressWarnings("all") also suppresses unused warning token
				if (irritants != foundIrritants[iSuppress]) { // mismatch, some warning tokens were unused
					MemberValuePair[] pairs = annotation.memberValuePairs();
					pairLoop: for (int iPair = 0, pairCount = pairs.length; iPair < pairCount; iPair++) {
						MemberValuePair pair = pairs[iPair];
						if (CharOperation.equals(pair.name, TypeConstants.VALUE)) {
							Expression value = pair.value;
							if (value instanceof ArrayInitializer) {
								ArrayInitializer initializer = (ArrayInitializer) value;
								Expression[] inits = initializer.expressions;
								if (inits != null) {
									for (int iToken = 0, tokenCount = inits.length; iToken < tokenCount; iToken++) {
										Constant cst = inits[iToken].constant;
										if (cst != Constant.NotAConstant && cst.typeID() == TypeIds.T_JavaLangString) {
											IrritantSet tokenIrritants = CompilerOptions.warningTokenToIrritants(cst.stringValue());
											if (tokenIrritants != null) {
												if (!tokenIrritants.areAllSet() // no complaint against @SuppressWarnings("all")
														&& (foundIrritants[iSuppress] == null || !foundIrritants[iSuppress].isAnySet(tokenIrritants))) { // if irritant had no matching problem
													if (unusedWarningTokenIsWarning) {
														int start = value.sourceStart, end = value.sourceEnd;
														nextSuppress: for (int jSuppress = iSuppress - 1; jSuppress >= 0; jSuppress--) {
															long position = this.suppressWarningScopePositions[jSuppress];
															int startSuppress = (int) (position >>> 32);
															int endSuppress = (int) position;
															if (start < startSuppress) continue nextSuppress;
															if (end > endSuppress) continue nextSuppress;
															if (this.suppressWarningIrritants[jSuppress].areAllSet()) break pairLoop; // suppress all?
														}
													}
													int id = options.getIgnoredIrritant(tokenIrritants);
													if (id > 0) {
														String key = CompilerOptions.optionKeyFromIrritant(id);
														this.scope.problemReporter().problemNotAnalysed(inits[iToken], key);
													} else {
														this.scope.problemReporter().unusedWarningToken(inits[iToken]);
													}
												}
											}
										}
									}
								}
							} else {
								Constant cst = value.constant;
								if (cst != Constant.NotAConstant && cst.typeID() == T_JavaLangString) {
									IrritantSet tokenIrritants = CompilerOptions.warningTokenToIrritants(cst.stringValue());
									if (tokenIrritants != null) {
										if (!tokenIrritants.areAllSet() // no complaint against @SuppressWarnings("all")
												&& (foundIrritants[iSuppress] == null || !foundIrritants[iSuppress].isAnySet(tokenIrritants))) { // if irritant had no matching problem
											if (unusedWarningTokenIsWarning) {
												int start = value.sourceStart, end = value.sourceEnd;
												nextSuppress: for (int jSuppress = iSuppress - 1; jSuppress >= 0; jSuppress--) {
													long position = this.suppressWarningScopePositions[jSuppress];
													int startSuppress = (int) (position >>> 32);
													int endSuppress = (int) position;
													if (start < startSuppress) continue nextSuppress;
													if (end > endSuppress) continue nextSuppress;
													if (this.suppressWarningIrritants[jSuppress].areAllSet()) break pairLoop; // suppress all?
												}
											}
											int id = options.getIgnoredIrritant(tokenIrritants);
											if (id > 0) {
												String key = CompilerOptions.optionKeyFromIrritant(id);
												this.scope.problemReporter().problemNotAnalysed(value, key);
											} else {
												this.scope.problemReporter().unusedWarningToken(value);
											}
										}
									}
								}
							}
							break pairLoop;
						}
					}
				}
			}
		}
	}
}

/**
 * Bytecode generation
 */
public void generateCode() {
	if (this.ignoreFurtherInvestigation) {
		if (this.types != null) {
			for (int i = 0, count = this.types.length; i < count; i++) {
				this.types[i].ignoreFurtherInvestigation = true;
				// propagate the flag to request problem type creation
				this.types[i].generateCode(this.scope);
			}
		}
		return;
	}
	try {
		if (this.types != null) {
			for (int i = 0, count = this.types.length; i < count; i++)
				this.types[i].generateCode(this.scope);
		}
		if (this.moduleDeclaration != null) {
			this.moduleDeclaration.generateCode();
		}
	} catch (AbortCompilationUnit e) {
		// ignore
	}
}

@Override
public CompilationUnitDeclaration getCompilationUnitDeclaration() {
	return this;
}

public char[] getFileName() {
	return this.compilationResult.getFileName();
}

public char[] getMainTypeName() {
	if (this.compilationResult.compilationUnit == null) {
		char[] fileName = this.compilationResult.getFileName();

		int start = CharOperation.lastIndexOf('/', fileName) + 1;
		if (start == 0 || start < CharOperation.lastIndexOf('\\', fileName))
			start = CharOperation.lastIndexOf('\\', fileName) + 1;

		int end = CharOperation.lastIndexOf('.', fileName);
		if (end == -1)
			end = fileName.length;

		return CharOperation.subarray(fileName, start, end);
	} else {
		return this.compilationResult.compilationUnit.getMainTypeName();
	}
}

public boolean isEmpty() {
	return (this.currentPackage == null) && (this.imports == null) && (this.types == null);
}

public boolean isPackageInfo() {
	return CharOperation.equals(getMainTypeName(), TypeConstants.PACKAGE_INFO_NAME);
}

public boolean isModuleInfo() {
	return CharOperation.equals(getMainTypeName(), TypeConstants.MODULE_INFO_NAME);
}

public boolean isSuppressed(CategorizedProblem problem) {
	if (this.suppressWarningsCount == 0) return false;
	int irritant = ProblemReporter.getIrritant(problem.getID());
	if (irritant == 0) return false;
	int start = problem.getSourceStart();
	int end = problem.getSourceEnd();
	nextSuppress: for (int iSuppress = 0, suppressCount = this.suppressWarningsCount; iSuppress < suppressCount; iSuppress++) {
		long position = this.suppressWarningScopePositions[iSuppress];
		int startSuppress = (int) (position >>> 32);
		int endSuppress = (int) position;
		if (start < startSuppress) continue nextSuppress;
		if (end > endSuppress) continue nextSuppress;
		if (this.suppressWarningIrritants[iSuppress].isSet(irritant))
			return true;
	}
	return false;
}

public boolean hasFunctionalTypes() {
	return this.compilationResult.hasFunctionalTypes;
}

@Override
public boolean hasErrors() {
	return this.ignoreFurtherInvestigation;
}

@Override
public StringBuffer print(int indent, StringBuffer output) {
	if (this.currentPackage != null) {
		printIndent(indent, output).append("package "); //$NON-NLS-1$
		this.currentPackage.print(0, output, false).append(";\n"); //$NON-NLS-1$
	}
	if (this.imports != null)
		for (int i = 0; i < this.imports.length; i++) {
			printIndent(indent, output).append("import "); //$NON-NLS-1$
			ImportReference currentImport = this.imports[i];
			if (currentImport.isStatic()) {
				output.append("static "); //$NON-NLS-1$
			}
			currentImport.print(0, output).append(";\n"); //$NON-NLS-1$
		}
	if (this.moduleDeclaration != null) {
		this.moduleDeclaration.print(indent, output).append("\n"); //$NON-NLS-1$
	} else if (this.types != null) {
		for (int i = 0; i < this.types.length; i++) {
			this.types[i].print(indent, output).append("\n"); //$NON-NLS-1$
		}
	}
	return output;
}

/*
 * Force inner local types to update their innerclass emulation
 */
public void propagateInnerEmulationForAllLocalTypes() {
	this.isPropagatingInnerClassEmulation = true;
	for (int i = 0, max = this.localTypeCount; i < max; i++) {
		LocalTypeBinding localType = this.localTypes[i];
		// only propagate for reachable local types
		if ((localType.scope.referenceType().bits & IsReachable) != 0) {
			localType.updateInnerEmulationDependents();
		}
	}
}

public void recordStringLiteral(StringLiteral literal, boolean fromRecovery) {
	if (this.stringLiteralsStart != null) {
		if (this.stringLiteralsStart.contains(literal.sourceStart)) return;
		this.stringLiteralsStart.add(literal.sourceStart);
	} else if (fromRecovery) {
		this.stringLiteralsStart = new HashSetOfInt(this.stringLiteralsPtr + STRING_LITERALS_INCREMENT);
		for (int i = 0; i < this.stringLiteralsPtr; i++) {
			this.stringLiteralsStart.add(this.stringLiterals[i].sourceStart);
		}

		if (this.stringLiteralsStart.contains(literal.sourceStart)) return;
		this.stringLiteralsStart.add(literal.sourceStart);
	}

	if (this.stringLiterals == null) {
		this.stringLiterals = new StringLiteral[STRING_LITERALS_INCREMENT];
		this.stringLiteralsPtr = 0;
	} else {
		int stackLength = this.stringLiterals.length;
		if (this.stringLiteralsPtr == stackLength) {
			System.arraycopy(
				this.stringLiterals,
				0,
				this.stringLiterals = new StringLiteral[stackLength + STRING_LITERALS_INCREMENT],
				0,
				stackLength);
		}
	}
	this.stringLiterals[this.stringLiteralsPtr++] = literal;
}

private boolean isLambdaExpressionCopyContext(ReferenceContext context) {
	if (context instanceof LambdaExpression && context != ((LambdaExpression) context).original())
		return true; // Do not record from copies. See https://bugs.eclipse.org/bugs/show_bug.cgi?id=441929
	Scope cScope = context instanceof AbstractMethodDeclaration ? ((AbstractMethodDeclaration) context).scope :
		context instanceof TypeDeclaration ? ((TypeDeclaration) context).scope :
		context instanceof LambdaExpression ? ((LambdaExpression) context).scope :
			null;
	return cScope != null ? isLambdaExpressionCopyContext(cScope.parent.referenceContext()) : false;
}
public void recordSuppressWarnings(IrritantSet irritants, Annotation annotation, int scopeStart, int scopeEnd, ReferenceContext context) {
	if (isLambdaExpressionCopyContext(context))
		return; // Do not record from copies. See https://bugs.eclipse.org/bugs/show_bug.cgi?id=441929

	if (this.suppressWarningIrritants == null) {
		this.suppressWarningIrritants = new IrritantSet[3];
		this.suppressWarningAnnotations = new Annotation[3];
		this.suppressWarningScopePositions = new long[3];
	} else if (this.suppressWarningIrritants.length == this.suppressWarningsCount) {
		System.arraycopy(this.suppressWarningIrritants, 0,this.suppressWarningIrritants = new IrritantSet[2*this.suppressWarningsCount], 0, this.suppressWarningsCount);
		System.arraycopy(this.suppressWarningAnnotations, 0,this.suppressWarningAnnotations = new Annotation[2*this.suppressWarningsCount], 0, this.suppressWarningsCount);
		System.arraycopy(this.suppressWarningScopePositions, 0,this.suppressWarningScopePositions = new long[2*this.suppressWarningsCount], 0, this.suppressWarningsCount);
	}
	final long scopePositions = ((long)scopeStart<<32) + scopeEnd;
	for (int i = 0, max = this.suppressWarningsCount; i < max; i++) {
		if (this.suppressWarningAnnotations[i] == annotation
				&& this.suppressWarningScopePositions[i] == scopePositions
				&& this.suppressWarningIrritants[i].hasSameIrritants(irritants)) {
			// annotation data already recorded
			return;
		}
	}
	this.suppressWarningIrritants[this.suppressWarningsCount] = irritants;
	this.suppressWarningAnnotations[this.suppressWarningsCount] = annotation;
	this.suppressWarningScopePositions[this.suppressWarningsCount++] = scopePositions;
}

/*
 * Keep track of all local types, so as to update their innerclass
 * emulation later on.
 */
public void record(LocalTypeBinding localType) {
	if (this.localTypeCount == 0) {
		this.localTypes = new LocalTypeBinding[5];
	} else if (this.localTypeCount == this.localTypes.length) {
		System.arraycopy(this.localTypes, 0, (this.localTypes = new LocalTypeBinding[this.localTypeCount * 2]), 0, this.localTypeCount);
	}
	this.localTypes[this.localTypeCount++] = localType;
}

/*
 * Keep track of all lambda/method reference expressions, so as to be able to look it up later without
 * having to traverse AST. Return the "ordinal" returned by the enclosing type.
 */
public int record(FunctionalExpression expression) {
	if (this.functionalExpressionsCount == 0) {
		this.functionalExpressions = new FunctionalExpression[5];
	} else if (this.functionalExpressionsCount == this.functionalExpressions.length) {
		System.arraycopy(this.functionalExpressions, 0, (this.functionalExpressions = new FunctionalExpression[this.functionalExpressionsCount * 2]), 0, this.functionalExpressionsCount);
	}
	this.functionalExpressions[this.functionalExpressionsCount++] = expression;
	return expression.enclosingScope.classScope().referenceContext.record(expression);
}

public void resolve() {
	int startingTypeIndex = 0;
	boolean isPackageInfo = isPackageInfo();
	boolean isModuleInfo = isModuleInfo();
	if (this.types != null && isPackageInfo) {
		// resolve synthetic type declaration
		final TypeDeclaration syntheticTypeDeclaration = this.types[0];
		// set empty javadoc to avoid missing warning (see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=95286)
		if (syntheticTypeDeclaration.javadoc == null) {
			syntheticTypeDeclaration.javadoc = new Javadoc(syntheticTypeDeclaration.declarationSourceStart, syntheticTypeDeclaration.declarationSourceStart);
		}
		syntheticTypeDeclaration.resolve(this.scope);
		/*
		 * resolve javadoc package if any, skip this step if we don't have a valid scope due to an earlier error (bug 252555)
		 * we do it now as the javadoc in the fake type won't be resolved. The peculiar usage of MethodScope to resolve the
		 * package level javadoc is because the CU level resolve method	is a NOP to mimic Javadoc's behavior and can't be used
		 * as such.
		 */
		if (this.javadoc != null && syntheticTypeDeclaration.staticInitializerScope != null) {
			this.javadoc.resolve(syntheticTypeDeclaration.staticInitializerScope);
		}
		startingTypeIndex = 1;
	} else if (this.moduleDeclaration != null && isModuleInfo) {
		if (this.javadoc != null) {
			this.javadoc.resolve((MethodScope)this.moduleDeclaration.scope);
		} else if (this.moduleDeclaration.binding != null) {
			ProblemReporter reporter = this.scope.problemReporter();
			int severity = reporter.computeSeverity(IProblem.JavadocMissing);
			if (severity != ProblemSeverities.Ignore) {
				reporter.javadocModuleMissing(this.moduleDeclaration.declarationSourceStart, this.moduleDeclaration.bodyStart,
						severity);
			}
		}
	} else {
		// resolve compilation unit javadoc package if any
		if (this.javadoc != null) {
			this.javadoc.resolve(this.scope);
		}
	}
	if (this.currentPackage != null && this.currentPackage.annotations != null && !isPackageInfo) {
		this.scope.problemReporter().invalidFileNameForPackageAnnotations(this.currentPackage.annotations[0]);
	}
	try {
		if (this.types != null) {
			for (int i = startingTypeIndex, count = this.types.length; i < count; i++) {
				this.types[i].resolve(this.scope);
			}
		}
		if (!this.compilationResult.hasMandatoryErrors()) checkUnusedImports();
		reportNLSProblems();
	} catch (AbortCompilationUnit e) {
		this.ignoreFurtherInvestigation = true;
		return;
	}
}

private void reportNLSProblems() {
	if (this.nlsTags != null || this.stringLiterals != null) {
		final int stringLiteralsLength = this.stringLiteralsPtr;
		final int nlsTagsLength = this.nlsTags == null ? 0 : this.nlsTags.length;
		if (stringLiteralsLength == 0) {
			if (nlsTagsLength != 0) {
				for (int i = 0; i < nlsTagsLength; i++) {
					NLSTag tag = this.nlsTags[i];
					if (tag != null) {
						this.scope.problemReporter().unnecessaryNLSTags(tag.start, tag.end);
					}
				}
			}
		} else if (nlsTagsLength == 0) {
			// resize string literals
			if (this.stringLiterals.length != stringLiteralsLength) {
				System.arraycopy(this.stringLiterals, 0, (this.stringLiterals = new StringLiteral[stringLiteralsLength]), 0, stringLiteralsLength);
			}
			Arrays.sort(this.stringLiterals, STRING_LITERAL_COMPARATOR);
			for (int i = 0; i < stringLiteralsLength; i++) {
				this.scope.problemReporter().nonExternalizedStringLiteral(this.stringLiterals[i]);
			}
		} else {
			// need to iterate both arrays to find non matching elements
			if (this.stringLiterals.length != stringLiteralsLength) {
				System.arraycopy(this.stringLiterals, 0, (this.stringLiterals = new StringLiteral[stringLiteralsLength]), 0, stringLiteralsLength);
			}
			Arrays.sort(this.stringLiterals, STRING_LITERAL_COMPARATOR);
			int indexInLine = 1;
			int lastLineNumber = -1;
			StringLiteral literal = null;
			int index = 0;
			int i = 0;
			stringLiteralsLoop: for (; i < stringLiteralsLength; i++) {
				literal = this.stringLiterals[i];
				final int literalLineNumber = literal.lineNumber;
				if (lastLineNumber != literalLineNumber) {
					indexInLine = 1;
					lastLineNumber = literalLineNumber;
				} else {
					indexInLine++;
				}
				if (index < nlsTagsLength) {
					nlsTagsLoop: for (; index < nlsTagsLength; index++) {
						NLSTag tag = this.nlsTags[index];
						if (tag == null) continue nlsTagsLoop;
						int tagLineNumber = tag.lineNumber;
						if (literalLineNumber < tagLineNumber) {
							this.scope.problemReporter().nonExternalizedStringLiteral(literal);
							continue stringLiteralsLoop;
						} else if (literalLineNumber == tagLineNumber) {
							if (tag.index == indexInLine) {
								this.nlsTags[index] = null;
								index++;
								continue stringLiteralsLoop;
							} else {
								nlsTagsLoop2: for (int index2 = index + 1; index2 < nlsTagsLength; index2++) {
									NLSTag tag2 = this.nlsTags[index2];
									if (tag2 == null) continue nlsTagsLoop2;
									int tagLineNumber2 = tag2.lineNumber;
									if (literalLineNumber == tagLineNumber2) {
										if (tag2.index == indexInLine) {
											this.nlsTags[index2] = null;
											continue stringLiteralsLoop;
										} else {
											continue nlsTagsLoop2;
										}
									} else {
										this.scope.problemReporter().nonExternalizedStringLiteral(literal);
										continue stringLiteralsLoop;
									}
								}
								this.scope.problemReporter().nonExternalizedStringLiteral(literal);
								continue stringLiteralsLoop;
							}
						} else {
							this.scope.problemReporter().unnecessaryNLSTags(tag.start, tag.end);
							continue nlsTagsLoop;
						}
					}
				}
				// all nls tags have been processed, so remaining string literals are not externalized
				break stringLiteralsLoop;
			}
			for (; i < stringLiteralsLength; i++) {
				this.scope.problemReporter().nonExternalizedStringLiteral(this.stringLiterals[i]);
			}
			if (index < nlsTagsLength) {
				for (; index < nlsTagsLength; index++) {
					NLSTag tag = this.nlsTags[index];
					if (tag != null) {
						this.scope.problemReporter().unnecessaryNLSTags(tag.start, tag.end);
					}
				}
			}
		}
	}
}

@Override
public void tagAsHavingErrors() {
	this.ignoreFurtherInvestigation = true;
}

@Override
public void tagAsHavingIgnoredMandatoryErrors(int problemId) {
	// Nothing to do for this context;
}

public void traverse(ASTVisitor visitor, CompilationUnitScope unitScope) {
	traverse(visitor, unitScope, true);
}
public void traverse(ASTVisitor visitor, CompilationUnitScope unitScope, boolean skipOnError) {
	if (skipOnError && this.ignoreFurtherInvestigation)
		return;
	try {
		if (visitor.visit(this, this.scope)) {
			if (this.types != null && isPackageInfo()) {
	            // resolve synthetic type declaration
				final TypeDeclaration syntheticTypeDeclaration = this.types[0];
				// resolve javadoc package if any
				final MethodScope methodScope = syntheticTypeDeclaration.staticInitializerScope;
				// Don't traverse in null scope and invite trouble a la bug 252555.
				if (this.javadoc != null && methodScope != null) {
					this.javadoc.traverse(visitor, methodScope);
				}
				// Don't traverse in null scope and invite trouble a la bug 252555.
				if (this.currentPackage != null && methodScope != null) {
					final Annotation[] annotations = this.currentPackage.annotations;
					if (annotations != null) {
						int annotationsLength = annotations.length;
						for (int i = 0; i < annotationsLength; i++) {
							annotations[i].traverse(visitor, methodScope);
						}
					}
				}
			}
			if (this.currentPackage != null) {
				this.currentPackage.traverse(visitor, this.scope);
			}
			if (this.imports != null) {
				int importLength = this.imports.length;
				for (int i = 0; i < importLength; i++) {
					this.imports[i].traverse(visitor, this.scope);
				}
			}
			if (this.types != null) {
				int typesLength = this.types.length;
				for (int i = 0; i < typesLength; i++) {
					this.types[i].traverse(visitor, this.scope);
				}
			}
			if (this.isModuleInfo() && this.moduleDeclaration != null) {
				this.moduleDeclaration.traverse(visitor, this.scope);
			}
		}
		visitor.endVisit(this, this.scope);
	} catch (AbortCompilationUnit e) {
		// ignore
	}
}
public ModuleBinding module(LookupEnvironment environment) {
	if (this.moduleDeclaration != null) {
		ModuleBinding binding = this.moduleDeclaration.binding;
		if (binding != null)
			return binding;
	}
	if (this.compilationResult != null) {
		ICompilationUnit compilationUnit = this.compilationResult.compilationUnit;
		if (compilationUnit != null)
			return compilationUnit.module(environment);
	}
	return environment.module;
}
}
