<commit_before>#region license
// Copyright (c) 2003, 2004, 2005 <NAME> (<EMAIL>)
// All rights reserved.
// 
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
// 
//     * Redistributions of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above copyright notice,
//     this list of conditions and the following disclaimer in the documentation
//     and/or other materials provided with the distribution.
//     * Neither the name of <NAME> nor the names of its
//     contributors may be used to endorse or promote products derived from this
//     software without specific prior written permission.
// 
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endregion

using System;
using System.Collections.Generic;
using System.Linq;
using Boo.Lang.Compiler.Ast;
using Boo.Lang.Compiler.TypeSystem;
using Boo.Lang.Compiler.TypeSystem.Internal;
using Boo.Lang.Compiler.TypeSystem.Services;
using Boo.Lang.Compiler.Util;

namespace Boo.Lang.Compiler.Steps
{
	public class ProcessInheritedAbstractMembers : AbstractVisitorCompilerStep, ITypeMemberReifier
	{
		private List<TypeDefinition> _newAbstractClasses;
		private Hash _classDefinitionList;
		private int _depth;
		private Set<IEntity> _explicitMembers;

		override public void Run()
		{	
			_newAbstractClasses = new List<TypeDefinition>();
			_classDefinitionList = new Hash();

			Visit(CompileUnit.Modules);

			_classDefinitionList.Clear();
			ProcessNewAbstractClasses();
		}

		override public void Dispose()
		{
			_newAbstractClasses = null;
			base.Dispose();
		}

		override public void OnProperty(Property node)
		{
			if (node.IsAbstract && null == node.Type)
				node.Type = CodeBuilder.CreateTypeReference(TypeSystemServices.ObjectType);

			ExplicitMemberInfo explicitInfo = node.ExplicitInfo;
			if (null != explicitInfo)
			{
				Visit(explicitInfo);
				if (null != explicitInfo.Entity)
					ProcessPropertyImplementation(node, (IProperty) explicitInfo.Entity);
			}
		}

		override public void OnMethod(Method node)
		{
			if (node.IsAbstract && null == node.ReturnType)
				node.ReturnType = CodeBuilder.CreateTypeReference(TypeSystemServices.VoidType);

			ExplicitMemberInfo explicitInfo = node.ExplicitInfo;
			if (null != explicitInfo)
			{
				Visit(explicitInfo);
				if (null != explicitInfo.Entity)
					ProcessMethodImplementation(node, (IMethod) explicitInfo.Entity);
			}
		}

		override public void OnExplicitMemberInfo(ExplicitMemberInfo node)
		{
			TypeMember member = (TypeMember)node.ParentNode;
			if (!CheckExplicitMemberValidity((IExplicitMember)member))
				return;

			IType interfaceType = GetEntity(node.InterfaceType);
			IEntity baseMember = FindImplementationFor((IMember) member.Entity, interfaceType);
			if (null == baseMember)
			{
				Error(CompilerErrorFactory.NotAMemberOfExplicitInterface(member, interfaceType));
				return;
			}

			TraceImplements(member, baseMember);
			node.Entity = baseMember;
		}

		bool CheckExplicitMemberValidity(IExplicitMember member)
		{
			Node node = (Node) member;
			IMember explicitMember = (IMember)GetEntity(node);
			IType declaringType = explicitMember.DeclaringType;
			if (!declaringType.IsClass)
			{
				Error(CompilerErrorFactory.InvalidTypeForExplicitMember(node, declaringType));
				return false;
			}

			IType targetInterface = GetType(member.ExplicitInfo.InterfaceType);
			if (!targetInterface.IsInterface)
			{
				Error(CompilerErrorFactory.InvalidInterfaceForInterfaceMember(node, member.ExplicitInfo.InterfaceType.Name));
				return false;
			}

			if (!declaringType.IsSubclassOf(targetInterface))
			{
				Error(CompilerErrorFactory.InterfaceImplForInvalidInterface(node, targetInterface.Name, ((TypeMember)node).Name));
				return false;
			}

			return true;
		}

		override public void LeaveInterfaceDefinition(InterfaceDefinition node)
		{
			MarkVisited(node);
		}

		override public void LeaveClassDefinition(ClassDefinition node)
		{
			MarkVisited(node);
			
			if (!_classDefinitionList.Contains(node.Name))
				_classDefinitionList.Add(node.Name, node);

			_explicitMembers = ExplicitlyImplementedMembersOn(node);
			foreach (TypeReference baseTypeRef in node.BaseTypes)<commit_msg>don't revisit nodes<commit_after>#region license
// Copyright (c) 2003, 2004, 2005 <NAME> (<EMAIL>)
// All rights reserved.
// 
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
// 
//     * Redistributions of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above copyright notice,
//     this list of conditions and the following disclaimer in the documentation
//     and/or other materials provided with the distribution.
//     * Neither the name of <NAME> nor the names of its
//     contributors may be used to endorse or promote products derived from this
//     software without specific prior written permission.
// 
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endregion

using System;
using System.Collections.Generic;
using System.Linq;
using Boo.Lang.Compiler.Ast;
using Boo.Lang.Compiler.TypeSystem;
using Boo.Lang.Compiler.TypeSystem.Internal;
using Boo.Lang.Compiler.TypeSystem.Services;
using Boo.Lang.Compiler.Util;

namespace Boo.Lang.Compiler.Steps
{
	public class ProcessInheritedAbstractMembers : AbstractVisitorCompilerStep, ITypeMemberReifier
	{
		private List<TypeDefinition> _newAbstractClasses;
		private Hash _classDefinitionList;
		private int _depth;
		private Set<IEntity> _explicitMembers;

		override public void Run()
		{	
			_newAbstractClasses = new List<TypeDefinition>();
			_classDefinitionList = new Hash();

			Visit(CompileUnit.Modules);

			_classDefinitionList.Clear();
			ProcessNewAbstractClasses();
		}

		override public void Dispose()
		{
			_newAbstractClasses = null;
			base.Dispose();
		}

		override public void OnProperty(Property node)
		{
			if (node.IsAbstract && null == node.Type)
				node.Type = CodeBuilder.CreateTypeReference(TypeSystemServices.ObjectType);

			ExplicitMemberInfo explicitInfo = node.ExplicitInfo;
			if (null != explicitInfo)
			{
				Visit(explicitInfo);
				if (null != explicitInfo.Entity)
					ProcessPropertyImplementation(node, (IProperty) explicitInfo.Entity);
			}
		}

		override public void OnMethod(Method node)
		{
			if (node.IsAbstract && null == node.ReturnType)
				node.ReturnType = CodeBuilder.CreateTypeReference(TypeSystemServices.VoidType);

			ExplicitMemberInfo explicitInfo = node.ExplicitInfo;
			if (null != explicitInfo)
			{
				Visit(explicitInfo);
				if (null != explicitInfo.Entity)
					ProcessMethodImplementation(node, (IMethod) explicitInfo.Entity);
			}
		}

		override public void OnExplicitMemberInfo(ExplicitMemberInfo node)
		{
			TypeMember member = (TypeMember)node.ParentNode;
			if (!CheckExplicitMemberValidity((IExplicitMember)member))
				return;

			IType interfaceType = GetEntity(node.InterfaceType);
			IEntity baseMember = FindImplementationFor((IMember) member.Entity, interfaceType);
			if (null == baseMember)
			{
				Error(CompilerErrorFactory.NotAMemberOfExplicitInterface(member, interfaceType));
				return;
			}

			TraceImplements(member, baseMember);
			node.Entity = baseMember;
		}

		bool CheckExplicitMemberValidity(IExplicitMember member)
		{
			Node node = (Node) member;
			IMember explicitMember = (IMember)GetEntity(node);
			IType declaringType = explicitMember.DeclaringType;
			if (!declaringType.IsClass)
			{
				Error(CompilerErrorFactory.InvalidTypeForExplicitMember(node, declaringType));
				return false;
			}

			IType targetInterface = GetType(member.ExplicitInfo.InterfaceType);
			if (!targetInterface.IsInterface)
			{
				Error(CompilerErrorFactory.InvalidInterfaceForInterfaceMember(node, member.ExplicitInfo.InterfaceType.Name));
				return false;
			}

			if (!declaringType.IsSubclassOf(targetInterface))
			{
				Error(CompilerErrorFactory.InterfaceImplForInvalidInterface(node, targetInterface.Name, ((TypeMember)node).Name));
				return false;
			}

			return true;
		}

		public override bool EnterInterfaceDefinition(InterfaceDefinition node)
		{
			return !WasVisited(node);
		}

		override public void LeaveInterfaceDefinition(InterfaceDefinition node)
		{
			MarkVisited(node);
		}

		public override bool EnterClassDefinition(ClassDefinition node)
		{
			return !WasVisited(node);
		}

		override public void LeaveClassDefinition(ClassDefinition node)
		{
			MarkVisited(node);
			
			if (!_classDefinitionList.Contains(node.Name))
				_classDefinitionList.Add(node.Name, node);

			_explicitMembers = ExplicitlyImplementedMembersOn(node);
			foreach (TypeReference baseTypeRef in node.BaseTypes)
{'fraction_non_alphanumeric': 0.0841934250764526, 'fraction_numerical': 0.0022935779816513763, 'mean_word_length': 4.41386445938955, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1217228', 'n_tokens_mistral': 3316, 'n_tokens_neox': 2784, 'n_words': 847}