⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 attribution.cs

📁 C#编写的c#编译器
💻 CS
字号:
using System;
using System.Collections;
using Dom = DDW.CSharp.Dom;
using DDW.CSharp.SymbolTable;

namespace DDW.CSharp.Parse
{
	public class Attribution
	{
		private Attribution(){}

		public static void AttributeExpressions(ExpressionRootCollection erc)
		{
			Attribution atrib = new Attribution();
			foreach(ExpressionRoot er in erc)
			{
				atrib.ResolveType(er.Expression);
			}
		}
		#region CoverType(IDefinition, IDefinition)
		/// <summary>
		/// Returns the lowest common type of the two arguments, based on C#'s type conversion tables.
		/// </summary>
		/// <param name="type1">First type to compare.</param>
		/// <param name="type2">Second type to compare.</param>
		/// <returns>The common type.</returns>
		public static bool CoverType(IDefinition type1, IDefinition type2)
		{
			// todo: reutrn the IDef that solves the two. For testing just return true (eg had match)
			return true;
		}
		#endregion 
		#region ConvertDistance(IDefinition, IDefinition)
		/// <summary>
		/// Returns true if the origin type can auto convert to the target type.
		/// </summary>
		/// <param name="type1">The type to try to convert.</param>
		/// <param name="type2">The type we are trying to convert to.</param>
		/// <returns>The common type.</returns>
		public static int ConvertDistance(IDefinition origin, IDefinition target)
		{
			// todo: deal with null
			// built in has no declaration, so .Type will be null (for now)
			if(origin is BuiltInDefinition && target is BuiltInDefinition)
			{
				BuiltInDefinition obit = (BuiltInDefinition)origin;
				BuiltInDefinition tbit = (BuiltInDefinition)target;
				int bit = obit.ConvertDistance(tbit.LiteralType);
				return bit;
			}
			else if(origin.Type == target.Type)
			{
				return 0; // match
			}
			else if(origin.Type is Dom.TypeDecl && target.Type is Dom.TypeDecl)
			{
				Dom.TypeDecl otd = (Dom.TypeDecl)origin.Type;
				Dom.TypeDecl ttd = (Dom.TypeDecl)target.Type;
				int dtt =  otd.DistanceToType(ttd.Definition, 0);
				return dtt;
				//otd.
			}
			return Int32.MaxValue;
		}
		#endregion 
		
		#region ResolveOverload
		/// <summary>
		/// Picks the correct overload for a constructor, method, indexer, or operator. Returns null in the case of no defined constructor (use default).
		/// </summary>
		/// <param name="constructors"></param>
		/// <param name="parameters"></param>
		/// <returns></returns>
		private IDefinition ResolveOverload
			(OverloadableDefinition constructors, Dom.ParamCollection parameters)
		{			
			// TODO: maybe return a pre-defined 'default constructor' ref
			if(constructors == null) return null;

			IDefinition matchDef = null;
			int ovCount = constructors.Definitions.Count;
			int paramCount = parameters.Count;
			ArrayList matches = new ArrayList();
			ArrayList argLists = new ArrayList();
			foreach(IDefinition cdef in constructors.Definitions)
			{
				if(cdef.SourceGraph is Dom.IOverloadable)
				{
					Dom.ParamDeclCollection pdc = 
						((Dom.IOverloadable)cdef.SourceGraph).Parameters;
					// TODO: account for  params
					if(paramCount == pdc.Count)
					{
						matches.Add(cdef);
						argLists.Add(pdc);
					}
				}
			}
			// no overloads
			int mCount = matches.Count;
			if(mCount == 0) 
			{
				; // throw error
			}
			else if(mCount == 1) 
			{
				// easy case (because we assume code is correct)
				// - only one match for arg numbers
				matchDef = (IDefinition)matches[0];
			}
			else
			{
				int[] bestMatches = new int[paramCount];
				int invalid = Int32.MaxValue;
				// set to all invalid
				for(int i = 0; i < paramCount; i++) bestMatches[i] = invalid;
				int[] curMatches = new int[paramCount];
				// resolve overload by sig
				// The remaining methods will have the same number of args
				// so more points for a non cast match
				for(int i = 0; i < mCount; i++)
				{
					Dom.ParamDeclCollection curParamDecls = 
						(Dom.ParamDeclCollection)argLists[i];
					// check for params special case
					bool isParams = false;
					if(paramCount > 0)
					{
						isParams = 
							curParamDecls[paramCount - 1].IsParams;
					}
					bool isBetterMatch = true;
					for(int j = 0; j < paramCount; j++)
					{
						Dom.ParamDecl pd = (Dom.ParamDecl)curParamDecls[j];
						Dom.Param p = (Dom.Param)parameters[j];
						if(pd.Direction != p.Direction)
						{
							isBetterMatch = false;
							break;
						}
						else
						{
							// must resolve param expressions...
							IDefinition argDef = ResolveType(p.Value);
							IDefinition declDef = pd.Definition.Type.Definition;
							curMatches[j] = ConvertDistance(argDef, declDef);
							if(	curMatches[j] == Int32.MaxValue || 
								curMatches[j] > bestMatches[j]) 
							{
								isBetterMatch = false;
								break;
							}
						}
					}
					if(isBetterMatch)
					{
						// ignore check for ambig etc now, as we assume valid code
						bestMatches = curMatches;
						matchDef = (IDefinition)matches[i];
					}
				}
			}
			return matchDef;
		}
		#endregion

		private IDefinition ResolveType(Dom.Expression expr)
		{
			IDefinition retval = null;
			if(expr is Dom.PrimitiveExpr)
			{
				return ((Dom.PrimitiveExpr)expr).ResultType;
			}
			switch(expr.GraphType)
			{
				case Dom.GraphTypes.UnknownReference :
				{
					Dom.UnknownReference ur = (Dom.UnknownReference)expr;
					IDefinition declDef = ur.Definition;

					IDefinition tpDef = declDef.Type.Definition;
					// built ins have no declaration, so use self
					if(tpDef == null)
						tpDef = ur.Definition;

					if(tpDef.Id == 0)
					{
						IDefinition defLookup = tpDef.Scope.EnclosingScope.Lookup(tpDef.Name); 
						ur.Definition.Type = defLookup.SourceGraph;
					}
					ur.DeclaredType = ur.Definition.Type;
					retval = declDef.Type.Definition;
					break;
				}
				case Dom.GraphTypes.AssignExpr :
				{
					Dom.AssignExpr ae = (Dom.AssignExpr)expr;
					// ae.Left -- ignore Left for now
					ae.ResultType = ResolveType(ae.Right);
					retval = ae.ResultType;
					break;
				}
				case Dom.GraphTypes.ObjectCreateExpr :
				{
					Dom.ObjectCreateExpr oce = (Dom.ObjectCreateExpr)expr;
					oce.ResultType = oce.CreateType.Definition;
					Dom.IDeclaration decl = oce.ResultType.SourceGraph;
					
					if(decl is Dom.ClassDecl)
					{
						Dom.ClassDecl cd = (Dom.ClassDecl)decl;
						OverloadableDefinition constructors = cd.Constructors;
						oce.ConstructorDefinition = 
							ResolveOverload(constructors, oce.Parameters);
					}					
					else if(decl is Dom.StructDecl)
					{
						Dom.StructDecl sd = (Dom.StructDecl)decl;
						OverloadableDefinition constructors = sd.Constructors;
						oce.ConstructorDefinition = 
							ResolveOverload(constructors, oce.Parameters);
					}
					retval =  oce.ResultType;
					break;
				}
				case Dom.GraphTypes.MethodInvokeExpr :
				{
					Dom.MethodInvokeExpr mie = (Dom.MethodInvokeExpr)expr;
					IDefinition targ = GetTargetDef(mie.Target);
					OverloadableDefinition overloads = (OverloadableDefinition)targ;
					if(overloads != null)
					{
						mie.Target.Definition = 
							ResolveOverload(overloads, mie.Parameters);
					}
					retval = ResolveType(mie.Target);
					break;
				}
				case Dom.GraphTypes.MethodRef :
				{
					Dom.MethodRef mr = (Dom.MethodRef)expr;
					IDefinition targ = null; 
					if(mr.Definition != null) 
					{
						retval = mr.Definition;
					}
					else if(mr.Target != null)
					{
						targ = ResolveType(mr.Target);
						// swallow unknown refs
						if(mr.Target is Dom.UnknownReference) mr.Target = null;
						if(mr.MethodName != "")
						{
							retval = targ.Scope.Lookup(mr.MethodName);
							mr.Definition = retval;
						}
						else
						{
							retval = targ;
							mr.Definition = retval;
						}
					}
					break;
				}
				case Dom.GraphTypes.MemberAccess :
				{
					Dom.MemberAccess ma = (Dom.MemberAccess)expr;
					IDefinition targ = null; 
					if(ma.Definition != null) 
					{
						retval = ma.Definition;
					}
					else if(ma.Target != null)
					{
						targ = ResolveType(ma.Target);
						//if(ma.Target is Dom.UnknownReference) ma.Target = null;
						if(ma.MemberName != "")
						{
							retval = targ.Scope.Lookup(ma.MemberName);
						}
						else
						{
							retval = targ;
						}
					}
					break;
				}
			}
			return retval;
		}
		private IDefinition GetTargetDef(Dom.Expression expr)
		{
			IDefinition retval = null;
			switch (expr.GraphType)
			{
				case Dom.GraphTypes.MethodRef :
				{
					Dom.MethodRef mrf = ((Dom.MethodRef)expr);
					if(mrf.Definition == null)
					{
						mrf.Definition = GetTargetDef(mrf.Target);
					}
					if(mrf.Target is Dom.UnknownReference) mrf.Target = null;
					retval = mrf.Definition;
					break;
				}
				case Dom.GraphTypes.UnknownReference :
				{
					Dom.UnknownReference ur =((Dom.UnknownReference)expr);
					retval = ur.Definition.Scope.EnclosingScope.Lookup(ur.Definition.Name);

					break;
				}
				case Dom.GraphTypes.MemberAccess :
				{
					Dom.MemberAccess ma =((Dom.MemberAccess)expr);
					IDefinition ttype = ResolveType(ma.Target);
					//if(ma.Target is Dom.UnknownReference) ma.Target = null;
					retval = ttype.SourceGraph.Definition.Scope.Lookup(ma.MemberName);
					break;
				}
			}
			return retval;
		}
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -