示例#1
0
 /// <summary>
 /// Add a method to the type
 /// </summary>
 /// <param name="type">Type node</param>
 /// <param name="method">Method node</param>
 public void AddMethod(TypeNode type, MethodNode method)
 {
     if (type.Methods.Contains(method.Name))
     type.Methods[method.Name].Add(method);
       else
     type.Methods.Add(method.Name, new List<MethodNode> { method });
 }
示例#2
0
        /// <summary>
        /// Create an automatic ToString() method
        /// </summary>
        /// <param name="type">Type node</param>
        private void GenerateToString(TypeNode type)
        {
            var node = new MethodNode("ToString", new SignatureNode("string"), false);
              node.Virtual = true;

              node.Body.Statements.Add(Expr.Return(Expr.String(type.Name)));

              node.Owner = type;
              AddMethod(type, node);
        }
示例#3
0
        /// <summary>
        /// Create a default constructor without parameters
        /// </summary>
        /// <param name="type">Type node</param>
        private void GenerateDefaultCtor(TypeNode type)
        {
            var node = new MethodNode(".ctor", new SignatureNode("void"), false);
              node.Body.Statements.Add(Expr.Return());

              node.SetParameters();
              node.Owner = type;
              AddMethod(type, node);
        }
示例#4
0
        /// <summary>
        /// Create an automatic constructor to set all fields
        /// </summary>
        /// <param name="type">Type node</param>
        private void GenerateAutoCtor(TypeNode type)
        {
            var node = new MethodNode(".ctor", new SignatureNode("void"), false);

              var parameters = new HashList<ParameterNode>();
              int idx = 0;
              foreach(var curr in type.Fields)
              {
            var param = new ParameterNode("_" + curr, type.Fields[curr].Type, idx);
            parameters.Add("_" + curr, param);
            idx++;

            var assignNode = new IdentifierSetNode(curr, true);
            assignNode.Expression = new IdentifierGetNode("_" + curr);
            node.Body.Statements.Add(assignNode);
              }

              node.SetParameters(parameters);
              node.Owner = type;
              AddMethod(type, node);
        }
示例#5
0
        /// <summary>
        /// Create an automatic .Equal() method
        /// </summary>
        /// <param name="type">Type node</param>
        private void GenerateAutoComparator(TypeNode type)
        {
            var node = new MethodNode("equal", new SignatureNode("bool"), false);

              // define parameter
              var parameters = new HashList<ParameterNode>();
              var param = new ParameterNode("_obj", new SignatureNode(type.Name), 0);
              parameters.Add(param.Name, param);

              // generate series of comparisons
              foreach(var curr in type.Fields)
              {
            //
            // if(@<name> != _obj.<name>) return false;
            //
            node.Body.Statements.Add(
              Expr.If(
            Expr.Compare(
              Expr.IdentifierGet(curr, true),
              Lexer.LexemType.NotEqual,
              Expr.IdentifierGet(curr, Expr.IdentifierGet("_obj"))
            ),
            Expr.Return(
              Expr.Bool(true)
            )
              )
            );
              }

              // return true
              node.Body.Statements.Add(
            Expr.Return(
              Expr.Bool(true)
            )
              );

              node.SetParameters(parameters);
              node.Owner = type;
              AddMethod(type, node);
        }
示例#6
0
        /// <summary>
        /// Create underlying MethodReference in assembly
        /// </summary>
        /// <param name="method">Method to prepare</param>
        public void PrepareMethod(MethodNode method)
        {
            // check if method should be virtual and set it's parent to virtual too
              if (method.Name != ".ctor")
              {
            var shadowedMethod = FindShadowedMethod(method);
            if (shadowedMethod != null)
            {
              method.Virtual = shadowedMethod.Virtual = true;

              if (shadowedMethod.Method != null && !shadowedMethod.BuiltIn)
            (shadowedMethod.Method as MethodDefinition).IsVirtual = true;
            }
              }

              // calculate required attributes
              var attribs = MethodAttributes.HideBySig;
              if (method.Static)
            attribs |= MethodAttributes.Static;
              if (method.Virtual)
            attribs |= MethodAttributes.Virtual;
              if (method.Name == ".ctor" || method.Name == ".cctor")
            attribs |= MethodAttributes.SpecialName | MethodAttributes.RTSpecialName;

              if (method.Name == ".cctor")
            attribs |= MethodAttributes.Private;
              else
            attribs |= MethodAttributes.Public;

              // create method in assembly
              method.Type.CompiledType = ResolveType(method.Type);
              var nativeMethod = new MethodDefinition(method.Name, attribs, ResolveType(method.Type));
              method.Method = nativeMethod;
              method.Scope = new Utils.Scope(nativeMethod);
              ((TypeDefinition)method.Owner.Type).Methods.Add(nativeMethod);

              // add parameter info in assembly
              if(method.Parameters != null)
            foreach (var curr in method.Parameters)
              method.Method.Parameters.Add(new ParameterDefinition(curr, ParameterAttributes.None, ResolveType(method.Parameters[curr].Type)));
        }
示例#7
0
 /// <summary>
 /// Explicitly mark method as virtual
 /// </summary>
 /// <param name="method">Method to work on</param>
 public void MakeMethodVirtual(MethodNode method)
 {
     var nativeMethod = method.Method as MethodDefinition;
       if(nativeMethod != null)
     nativeMethod.Attributes |= MethodAttributes.Virtual;
       method.Virtual = true;
 }
示例#8
0
        /// <summary>
        /// Find out if there's a method that the current method overloads
        /// </summary>
        /// <param name="node">Method node</param>
        /// <returns></returns>
        public MethodNode FindShadowedMethod(MethodNode node)
        {
            var parentType = FindType(node.Owner.Parent);
              while(parentType != null)
              {
            if(parentType.Methods.Contains(node.Name))
            {
              var overloads = parentType.Methods[node.Name];
              var found = overloads.Find(curr => curr.Signature == node.Signature);
              if(found != null)
            return found;
            }

            parentType = FindType(parentType.Parent);
              }

              return null;
        }
示例#9
0
        /// <summary>
        /// Create a method in a type
        /// </summary>
        /// <param name="owner">Owner type node</param>
        /// <param name="name">Method name</param>
        /// <param name="type">Method return value type signature</param>
        /// <param name="parameters">Method parameters list</param>
        /// <param name="isStatic">Static flag</param>
        /// <returns></returns>
        public MethodNode CreateMethod(TypeNode owner, string name, SignatureNode type, HashList<ParameterNode> parameters = null, bool isStatic = false, bool prepare = false)
        {
            // cannot add methods to built-in types
              if (owner.BuiltIn)
            throw new CompilerException(String.Format(Resources.errExtendBuiltInType, owner.Name));

              // create method in assembly and in Mirelle Registry
              var method = new MethodNode(name, type, isStatic);

              method.SetParameters(parameters);

              // check if an identical method hasn't already been declared
              if (owner.Methods.Contains(method.Name))
              {
            if(owner.Methods[method.Name].Exists(curr => curr.Signature == method.Signature))
              throw new CompilerException(String.Format(Resources.errMethodRedefinition, method.Name, owner.Name));
              }

              // register method in the parent type
              AddMethod(owner, method);
              method.Owner = owner;

              if (prepare)
            PrepareMethod(method);

              return method;
        }
示例#10
0
        /// <summary>
        /// Import a method from any assembly into Mirelle registry
        /// </summary>
        /// <param name="baseType">Actual type</param>
        /// <param name="baseName">Method name within actual type</param>
        /// <param name="owner">Owner type name within Mirelle</param>
        /// <param name="name">Method name within mirelle</param>
        /// <param name="type">Type</param>
        /// <param name="isStatic">Static flag</param>
        /// <param name="parameters">Parameter list</param>
        /// <returns></returns>
        public MethodNode ImportMethod(Type baseType, string baseName, string owner, string name, string type, bool isStatic = false, params string[] parameters)
        {
            var ownerType = FindType(owner);
              if (ownerType == null)
            throw new CompilerException(String.Format(Resources.errTypeNotFound, owner));

              // find method in the base type and import it
              var types = new Type[parameters.Length];
              var idx = 0;
              foreach (var curr in parameters)
              {
            types[idx] = ResolveBasicType(curr);
            idx++;
              }

              MethodReference importedMethod;
              if(baseName == ".ctor")
            importedMethod = AssemblyImport(baseType.GetConstructor(types));
              else
            importedMethod = AssemblyImport(baseType.GetMethod(baseName, types));

              var typeNode = new SignatureNode(type);
              ResolveType(typeNode);
              var method = new MethodNode(name, typeNode, isStatic, true, importedMethod);

              // parameters
              var sb = new StringBuilder(name);
              idx = 0;
              foreach (var curr in parameters)
              {
            // declared as extension method ?
            // first parameter is the invoker itself, remove it from parameters list
            if (!importedMethod.HasThis && !isStatic && idx == 0)
            {
              idx++;
              continue;
            }

            var signNode = new SignatureNode(curr);
            sb.Append(" ");
            sb.Append(curr);
            var param = new ParameterNode("p" + idx.ToString(), signNode, idx);
            method.Parameters.Add(param.Name, param);
            idx++;
              }
              method.Signature = sb.ToString();

              // check if an identical method hasn't already been declared
              if (ownerType.Methods.Contains(method.Signature))
            throw new CompilerException(String.Format(Resources.errMethodRedefinition, method.Name, owner));

              // register method in the owner type
              AddMethod(ownerType, method);
              method.Owner = ownerType;
              return method;
        }
示例#11
0
 /// <summary>
 /// Call a method
 /// </summary>
 /// <param name="node"></param>
 /// <param name="method"></param>
 public void EmitCall(MethodNode node)
 {
     GetMethodProcessor().Emit((node.Virtual ? OpCodes.Callvirt : OpCodes.Call), node.Method);
 }
示例#12
0
 /// <summary>
 /// Create a new object using the constructor
 /// </summary>
 /// <param name="ctor">Constructor method node</param>
 /// <param name="method"></param>
 public void EmitNewObj(MethodNode ctor)
 {
     GetMethodProcessor().Emit(OpCodes.Newobj, ctor.Method);
 }
示例#13
0
 /// <summary>
 /// Call a virtual method
 /// </summary>
 /// <param name="node"></param>
 /// <param name="method"></param>
 public void EmitCallVirtual(MethodNode node)
 {
     GetMethodProcessor().Emit(OpCodes.Callvirt, node.Method);
 }