package dyvil.tools.compiler.ast.external;

import dyvil.tools.compiler.DyvilCompiler;
import dyvil.tools.compiler.ast.classes.IClass;
import dyvil.tools.compiler.ast.expression.IValue;
import dyvil.tools.compiler.ast.field.IDataMember;
import dyvil.tools.compiler.ast.header.ImportDeclaration;
import dyvil.tools.compiler.ast.method.IMethod;
import dyvil.tools.compiler.ast.method.MatchList;
import dyvil.tools.compiler.ast.parameter.IArguments;
import dyvil.tools.compiler.ast.structure.DyvilHeader;
import dyvil.tools.compiler.ast.type.IType;
import dyvil.tools.compiler.ast.type.alias.ITypeAlias;
import dyvil.tools.parsing.Name;

public class ExternalHeader extends DyvilHeader
{
	private static final int IMPORTS              = 1;
	private static final int INCLUDE_DECLARATIONS = 1 << 2;
	private static final int TYPE_ALIASES         = 1 << 3;

	private int resolved;

	public ExternalHeader(DyvilCompiler compiler)
	{
		super(compiler);
	}

	public ExternalHeader(DyvilCompiler compiler, Name name)
	{
		super(compiler, name);
	}

	private void resolveIncludeDeclarations()
	{
		this.resolved |= INCLUDE_DECLARATIONS;

		for (int i = 0; i < this.includeCount; i++)
		{
			this.includes[i].resolveTypes(null, this);
		}
	}

	@Override
	protected void resolveImports()
	{
		if ((this.resolved & INCLUDE_DECLARATIONS) == 0)
		{
			this.resolveIncludeDeclarations();
		}

		this.resolved |= IMPORTS;

		for (int i = 0; i < this.importCount; i++)
		{
			final ImportDeclaration declaration = this.importDeclarations[i];
			declaration.resolveTypes(null);
			declaration.resolve(null);
		}
	}

	private void resolveTypeAliases()
	{
		this.resolved |= TYPE_ALIASES;

		for (int i = 0; i < this.typeAliasCount; i++)
		{
			this.typeAliases[i].resolveTypes(null, this);
		}
	}

	@Override
	public IClass resolveClass(Name name)
	{
		if ((this.resolved & IMPORTS) == 0)
		{
			this.resolveImports();
		}
		return super.resolveClass(name);
	}

	@Override
	public IDataMember resolveField(Name name)
	{
		if ((this.resolved & IMPORTS) == 0)
		{
			this.resolveImports();
		}
		return super.resolveField(name);
	}

	@Override
	public ITypeAlias resolveTypeAlias(Name name, int arity)
	{
		if ((this.resolved & TYPE_ALIASES) == 0)
		{
			this.resolveTypeAliases();
		}

		return super.resolveTypeAlias(name, arity);
	}

	@Override
	public void getMethodMatches(MatchList<IMethod> list, IValue receiver, Name name, IArguments arguments)
	{
		if ((this.resolved & IMPORTS) == 0)
		{
			this.resolveImports();
		}
		super.getMethodMatches(list, receiver, name, arguments);
	}

	@Override
	public void getImplicitMatches(MatchList<IMethod> list, IValue value, IType targetType)
	{
		if ((this.resolved & IMPORTS) == 0)
		{
			this.resolveImports();
		}
		super.getImplicitMatches(list, value, targetType);
	}
}

@@ -117,333 +117,81 @@
 st.c
-lasses.IClass;%0Aimport dyvil.tools.compiler.ast.expression.IValue;%0Aimport dyvil.tools.compiler.ast.field.IDataMember;%0Aimport dyvil.tools.compiler.ast.header.ImportDeclaration;%0Aimport dyvil.tools.compiler.ast.method.IMethod;%0Aimport dyvil.tools.compiler.ast.method.MatchList;%0Aimport dyvil.tools.compiler.ast.parameter.IArguments
+ontext.IContext;%0Aimport dyvil.tools.compiler.ast.header.ImportDeclaration
 ;%0Aim
@@ -247,52 +247,8 @@
 er;%0A
-import dyvil.tools.compiler.ast.type.IType;%0A
 impo
@@ -438,65 +438,8 @@
  1;%0A
-%09private static final int INCLUDE_DECLARATIONS = 1 %3C%3C 2;%0A
 %09pri
@@ -492,9 +492,9 @@
  %3C%3C 
-3
+1
 ;%0A%0A%09
@@ -684,46 +684,47 @@
 %7D%0A%0A%09
-private void resolveIncludeDeclaration
+@Override%0A%09protected void resolveImport
 s()%0A
@@ -746,34 +746,21 @@
 ved %7C= I
-NCLUDE_DECLARATION
+MPORT
 S;%0A%0A%09%09fo
@@ -858,185 +858,8 @@
 %0A%09%09%7D
-%0A%09%7D%0A%0A%09@Override%0A%09protected void resolveImports()%0A%09%7B%0A%09%09if ((this.resolved & INCLUDE_DECLARATIONS) == 0)%0A%09%09%7B%0A%09%09%09this.resolveIncludeDeclarations();%0A%09%09%7D%0A%0A%09%09this.resolved %7C= IMPORTS;
 %0A%0A%09%09
@@ -1253,35 +1253,26 @@
 c IC
-lass resolveClass(Name name
+ontext getContext(
 )%0A%09%7B
@@ -1363,194 +1363,19 @@
 per.
-resolveClass(name);%0A%09%7D%0A%0A%09@Override%0A%09public IDataMember resolveField(Name name)%0A%09%7B%0A%09%09if ((this.resolved & IMPORTS) == 0)%0A%09%09%7B%0A%09%09%09this.resolveImports();%0A%09%09%7D%0A%09%09return super.resolveField(name
+getContext(
 );%0A%09
@@ -1583,493 +1583,7 @@
 ;%0A%09%7D
-%0A%0A%09@Override%0A%09public void getMethodMatches(MatchList%3CIMethod%3E list, IValue receiver, Name name, IArguments arguments)%0A%09%7B%0A%09%09if ((this.resolved & IMPORTS) == 0)%0A%09%09%7B%0A%09%09%09this.resolveImports();%0A%09%09%7D%0A%09%09super.getMethodMatches(list, receiver, name, arguments);%0A%09%7D%0A%0A%09@Override%0A%09public void getImplicitMatches(MatchList%3CIMethod%3E list, IValue value, IType targetType)%0A%09%7B%0A%09%09if ((this.resolved & IMPORTS) == 0)%0A%09%09%7B%0A%09%09%09this.resolveImports();%0A%09%09%7D%0A%09%09super.getImplicitMatches(list, value, targetType);%0A%09%7D
 %0A%7D%0A

Fix External Header Resolution