package dyvil.tools.compiler.ast.type.generic;

import dyvil.tools.compiler.ast.classes.IClass;
import dyvil.tools.compiler.ast.context.IContext;
import dyvil.tools.compiler.ast.generic.ITypeParameter;
import dyvil.tools.compiler.ast.modifiers.ModifierUtil;
import dyvil.tools.compiler.ast.type.IType;
import dyvil.tools.compiler.util.Markers;
import dyvil.tools.parsing.marker.Marker;
import dyvil.tools.parsing.marker.MarkerList;
import dyvil.tools.parsing.position.ICodePosition;

public class ResolvedGenericType extends ClassGenericType
{
	protected ICodePosition position;

	public ResolvedGenericType(ICodePosition position)
	{
		super();
		this.position = position;
	}

	public ResolvedGenericType(ICodePosition position, IClass iclass)
	{
		super(iclass);
		this.position = position;
	}

	public ResolvedGenericType(ICodePosition position, IClass iclass, IType[] typeArguments, int typeArgumentCount)
	{
		super(iclass, typeArguments, typeArgumentCount);
		this.position = position;
	}

	@Override
	public ICodePosition getPosition()
	{
		return this.position;
	}

	@Override
	public void setPosition(ICodePosition position)
	{
		this.position = position;
	}

	@Override
	public void checkType(MarkerList markers, IContext context, TypePosition position)
	{
		final IClass theClass = this.theClass;
		if (theClass != null)
		{
			ModifierUtil.checkVisibility(theClass, this.position, markers, context);
		}

		// Check if the Type Variable Bounds accept the supplied Type Arguments
		for (int i = 0; i < this.typeArgumentCount; i++)
		{
			final ITypeParameter typeVariable = this.theClass.getTypeParameter(i);
			final IType type = this.typeArguments[i];
			if (typeVariable != null && type.isResolved() && !typeVariable.isSuperTypeOf(type))
			{
				final Marker marker = Markers
						.semantic(type.getPosition(), "generic.type.incompatible", typeVariable.getName().qualified,
						          this.theClass.getFullName());
				marker.addInfo(Markers.getSemantic("generic.type", type));
				marker.addInfo(Markers.getSemantic("typeparameter.declaration", typeVariable));
				markers.add(marker);
			}
		}

		if (position == TypePosition.CLASS)
		{
			markers.add(Markers.semanticError(this.position, "type.class.generic"));
		}

		// If the position is a SUPER_TYPE position
		if (position == TypePosition.SUPER_TYPE || position == TypePosition.SUPER_TYPE_ARGUMENT)
		{
			position = TypePosition.SUPER_TYPE_ARGUMENT;
		}
		else
		{
			// Otherwise, resolve the type arguments with a GENERIC_ARGUMENT position
			position = TypePosition.GENERIC_ARGUMENT;
		}

		super.checkType(markers, context, position);
	}
}

@@ -1264,78 +1264,8 @@
 %0A%09%7B%0A
-%09%09final IClass theClass = this.theClass;%0A%09%09if (theClass != null)%0A%09%09%7B%0A%09
 %09%09Mo
@@ -1291,16 +1291,21 @@
 ibility(
+this.
 theClass
@@ -1339,20 +1339,16 @@
 ontext);
-%0A%09%09%7D
 %0A%0A%09%09// C
@@ -1422,45 +1422,118 @@
 %0A%09%09f
-or (int i = 0; i %3C this.typeArgumentC
+inal int count = Math.min(this.typeArgumentCount, this.theClass.typeParameterCount());%0A%09%09for (int i = 0; i %3C c
 ount
@@ -1666,39 +1666,16 @@
 i%5D;%0A
+%0A
 %09%09%09if (
-typeVariable != null && 
 type
@@ -1764,23 +1764,16 @@
  Markers
-%0A%09%09%09%09%09%09
 .semanti
@@ -1822,16 +1822,59 @@
 atible%22,
+%0A%09%09%09%09                                      
  typeVar
@@ -1903,24 +1903,8 @@
 ied,
-%0A%09%09%09%09%09%09         
  thi

Fix Generic Type Resolution