public override void VisitTypeNodeList(TypeNodeList types)
        {
            if (types == null)
            {
                return;
            }

            for (int i = 0, n = types.Count; i < n; i++)
            {
                var type = types[i];
                if (type == null)
                {
                    continue;
                }

                Class c = type as Class;
                if (c != null && HelperMethods.IsContractTypeForSomeOtherType(c))
                {
                    types[i] = null;
                }
                else
                {
                    // for nested types
                    this.VisitTypeNode(type);
                }
            }
        }
Пример #2
0
 public override TypeNodeList VisitTypeNodeList(TypeNodeList types)
 {
     if (types == null)
     {
         return(null);
     }
     for (int i = 0, n = types.Count; i < n; i++)
     {
         TypeNode type = types[i]; if (type == null)
         {
             continue;
         }
         if (this.Line != int.MinValue)
         {
             if (!type.SourceContext.Encloses(this.Line, this.Column))
             {
                 continue;
             }
         }
         else
         {
             if (!type.SourceContext.Encloses(this.SourceContext))
             {
                 continue;
             }
         }
         this.Visit(type);
         break;
     }
     return(types);
 }
Пример #3
0
 public void PopulateTypeList(TypeNodeList types, NamespaceList namespaces)
 {
     if (types == null)
     {
         Debug.Assert(false); return;
     }
     for (int i = 0, n = namespaces == null ? 0 : namespaces.Length; i < n; i++)
     {
         Namespace ns = namespaces[i];
         if (ns == null)
         {
             continue;
         }
         if (ns.NestedNamespaces != null)
         {
             this.PopulateTypeList(types, ns.NestedNamespaces);
         }
         TypeNodeList nTypes = ns.Types;
         for (int j = 0, m = nTypes == null ? 0 : nTypes.Length; j < m; j++)
         {
             TypeNode t = nTypes[j];
             if (t == null)
             {
                 continue;
             }
             this.PopulateTypeList(types, t);
         }
     }
 }
Пример #4
0
        public static TypeNode findType(string nsName, Identifier typeName)
        {
            if (typeName == null)
            {
                return(null);
            }
            TypeNodeList ns;

            if (allNamespaces == null || nsCached == null)
            {
                init();
            }
            if (!nsCached.TryGetValue(nsName, out ns))
            {
                ns = findAll(nsName);
            }

            TypeNodeList types = nsCached[nsName];

            for (int i = 0, n = types.Length; i < n; i++)
            {
                if (types[i].Name.Name == typeName.Name)
                {
                    return(types[i]);
                }
            }
            return(null);
        }
Пример #5
0
        private static void WriteMethod(Method method, TextWriter writer)
        {
            string name = method.Name.Name;

            WriteType(method.DeclaringType, writer);

            Method eiiMethod = null;

            if (method.IsPrivate && method.IsVirtual)
            {
                MethodList eiiMethods = method.ImplementedInterfaceMethods;
                if (eiiMethods.Count > 0)
                {
                    eiiMethod = eiiMethods[0];
                }
            }
            if (eiiMethod != null)   //explicitly implemented interface
            {
                TypeNode   eiiType   = eiiMethod.DeclaringType;
                TextWriter eiiWriter = new StringWriter();


                //we need to keep the param names instead of turning them into numbers
                //get the template to the right format
                if (eiiType != null && eiiType.Template != null)
                {
                    writer.Write(".");
                    WriteTemplate(eiiType, writer);
                }
                else //revert back to writing the type the old way if there is no template
                {
                    WriteType(eiiType, eiiWriter);
                    writer.Write(".");
                    writer.Write(eiiWriter.ToString().Replace('.', '#'));
                }

                writer.Write("#");
                writer.Write(eiiMethod.Name.Name);
            }
            else
            {
                writer.Write(".{0}", name);
            }
            if (method.IsGeneric)
            {
                TypeNodeList genericParameters = method.TemplateParameters;
                if (genericParameters != null)
                {
                    writer.Write("``{0}", genericParameters.Count);
                }
            }
            WriteParameters(method.Parameters, writer);
            // add ~ for conversion operators
            if ((name == "op_Implicit") || (name == "op_Explicit"))
            {
                writer.Write("~");
                WriteType(method.ReturnType, writer);
            }
        }
Пример #6
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="writer"></param>
        /// <param name="type">the current type being extended</param>
        /// <param name="extensionMethodTemplate">A reference to the extension method. For generic methods, this is a reference to the
        /// non-specialized method, e.g. System.Linq.Enumerable.Select``2.
        /// </param>
        /// <param name="specialization">When the current type implements or inherits from a specialization of a generic type,
        /// this parameter has a TypeNode for the type used as apecialization of the generic type's first template param.
        /// </param>
        private void AddExtensionMethod(XmlWriter writer, TypeNode type, Method extensionMethodTemplate, TypeNode specialization)
        {
            // If this is a specialization of a generic method, construct a Method object that describes the specialization
            Method extensionMethodTemplate2 = extensionMethodTemplate;

            if (extensionMethodTemplate2.IsGeneric && (specialization != null))
            {
                // the specialization type is the first of the method's template arguments
                TypeNodeList templateArgs = new TypeNodeList();
                templateArgs.Add(specialization);
                // add any additional template arguments
                for (int i = 1; i < extensionMethodTemplate.TemplateParameters.Count; i++)
                {
                    templateArgs.Add(extensionMethodTemplate.TemplateParameters[i]);
                }
                extensionMethodTemplate2 = extensionMethodTemplate.GetTemplateInstance(type, templateArgs);
            }
            TypeNode      extensionMethodTemplateReturnType = extensionMethodTemplate2.ReturnType;
            ParameterList extensionMethodTemplateParameters = extensionMethodTemplate2.Parameters;

            ParameterList extensionMethodParameters = new ParameterList();

            for (int i = 1; i < extensionMethodTemplateParameters.Count; i++)
            {
                Parameter extensionMethodParameter = extensionMethodTemplateParameters[i];
                extensionMethodParameters.Add(extensionMethodParameter);
            }
            Method extensionMethod = new Method(extensionMethodTemplate.DeclaringType, new AttributeList(), extensionMethodTemplate.Name, extensionMethodParameters, extensionMethodTemplate.ReturnType, null);

            extensionMethod.Flags = extensionMethodTemplate.Flags & ~MethodFlags.Static;

            // for generic methods, set the template args and params so the template data is included in the id and the method data
            if (extensionMethodTemplate2.IsGeneric)
            {
                extensionMethod.IsGeneric = true;
                if (specialization != null)
                {
                    // set the template args for the specialized generic method
                    extensionMethod.TemplateArguments = extensionMethodTemplate2.TemplateArguments;
                }
                else
                {
                    // set the generic template params for the non-specialized generic method
                    extensionMethod.TemplateParameters = extensionMethodTemplate2.TemplateParameters;
                }
            }

            // Get the id
            string extensionMethodTemplateId = reflector.ApiNamer.GetMemberName(extensionMethodTemplate);

            // write the element node
            writer.WriteStartElement("element");
            writer.WriteAttributeString("api", extensionMethodTemplateId);
            writer.WriteAttributeString("source", "extension");
            isExtensionMethod = true;
            reflector.WriteMember(extensionMethod);
            isExtensionMethod = false;
            writer.WriteEndElement();
        }
Пример #7
0
 private void StoreTypes(TypeNodeList types)
 {
     //Console.WriteLine("{0} types", types.Length);
     for (int i = 0; i < types.Count; i++)
     {
         StoreType(types[i]);
     }
 }
Пример #8
0
        protected virtual void VisitNamespace(Namespace space)
        {
            //Console.WriteLine("Visit Entity {0}",space.FullName);
            VisitEntity(space);
            TypeNodeList types = space.Types;

            VisitTypes(types);
        }
Пример #9
0
 public Specializer(Module targetModule, TypeNodeList pars, TypeNodeList args)
 {
     Debug.Assert(pars != null && pars.Count > 0);
     Debug.Assert(args != null && args.Count > 0);
     this.pars = pars;
     this.args = args;
     this.TargetModule = targetModule;
 }
Пример #10
0
 public override void LookupAnonymousTypes(Identifier ns, TypeNodeList atypes)
 {
     // 21 June 2005 -- For now, remove functionality of finding anonyous members: too slow,
     // and not needed for now since we are not allowing general quantifiers in contracts
     // But keep commented code in case we want to go back to it.
     return;
     //SpecSharpCompilerOptions coptions = this.currentOptions as SpecSharpCompilerOptions;
     //if (coptions != null && coptions.Compatibility) return;
     //base.LookupAnonymousTypes(ns, atypes);
 }
Пример #11
0
        private readonly TypeNode declaringType; // needed to copy anonymous delegates into

        public ReplaceResult(Method containingMethod, Local originalLocalForResult, Module assemblyBeingRewritten)
        {
            Contract.Requires(containingMethod != null);

            this.assemblyBeingRewritten = assemblyBeingRewritten;
            this.declaringType          = containingMethod.DeclaringType;
            this.topLevelMethodFormals  = containingMethod.TemplateParameters;
            this.originalLocalForResult = originalLocalForResult;
            this.delegateNestingLevel   = 0;
        }
Пример #12
0
        /// <summary>
        /// 
        /// </summary>
        /// <param name="writer"></param>
        /// <param name="type">the current type being extended</param>
        /// <param name="extensionMethodTemplate">A reference to the extension method. For generic methods, this is a reference to the 
        /// non-specialized method, e.g. System.Linq.Enumerable.Select``2.
        /// </param>
        /// <param name="specialization">When the current type implements or inherits from a specialization of a generic type,
        /// this parameter has a TypeNode for the type used as apecialization of the generic type's first template param. 
        /// </param>
        private void AddExtensionMethod(XmlWriter writer, TypeNode type, Method extensionMethodTemplate, TypeNode specialization)
        {
            // If this is a specialization of a generic method, construct a Method object that describes the specialization
            Method extensionMethodTemplate2 = extensionMethodTemplate;
            if (extensionMethodTemplate2.IsGeneric && (specialization != null))
            {
                // the specialization type is the first of the method's template arguments
                TypeNodeList templateArgs = new TypeNodeList();
                templateArgs.Add(specialization);
                // add any additional template arguments
                for (int i = 1; i < extensionMethodTemplate.TemplateParameters.Count; i++)
                    templateArgs.Add(extensionMethodTemplate.TemplateParameters[i]);
                extensionMethodTemplate2 = extensionMethodTemplate.GetTemplateInstance(type, templateArgs);
            }
            TypeNode extensionMethodTemplateReturnType = extensionMethodTemplate2.ReturnType;
            ParameterList extensionMethodTemplateParameters = extensionMethodTemplate2.Parameters;

            ParameterList extensionMethodParameters = new ParameterList();
            for (int i = 1; i < extensionMethodTemplateParameters.Count; i++)
            {
                Parameter extensionMethodParameter = extensionMethodTemplateParameters[i];
                extensionMethodParameters.Add(extensionMethodParameter);
            }
            Method extensionMethod = new Method(extensionMethodTemplate.DeclaringType, new AttributeList(), extensionMethodTemplate.Name, extensionMethodParameters, extensionMethodTemplate.ReturnType, null);
            extensionMethod.Flags = extensionMethodTemplate.Flags & ~MethodFlags.Static;

            // for generic methods, set the template args and params so the template data is included in the id and the method data
            if (extensionMethodTemplate2.IsGeneric)
            {
                extensionMethod.IsGeneric = true;
                if (specialization != null)
                {
                    // set the template args for the specialized generic method
                    extensionMethod.TemplateArguments = extensionMethodTemplate2.TemplateArguments;
                }
                else
                {
                    // set the generic template params for the non-specialized generic method
                    extensionMethod.TemplateParameters = extensionMethodTemplate2.TemplateParameters;
                }
            }

            // Get the id
            string extensionMethodTemplateId = reflector.ApiNamer.GetMemberName(extensionMethodTemplate);

            // write the element node
            writer.WriteStartElement("element");
            writer.WriteAttributeString("api", extensionMethodTemplateId);
            writer.WriteAttributeString("source", "extension");
            isExtensionMethod = true;
            reflector.WriteMember(extensionMethod);
            isExtensionMethod = false;
            writer.WriteEndElement();
        }
Пример #13
0
 private static bool IsSpecialized(TypeNode type)
 {
     for (TypeNode t = type; t != null; t = t.DeclaringType)
     {
         TypeNodeList templates = t.TemplateArguments;
         if ((templates != null) && (templates.Count > 0))
         {
             return(true);
         }
     }
     return(false);
 }
Пример #14
0
 public Checker(ErrorHandler errorHandler, TypeSystem typeSystem, TrivialHashtable scopeFor, TrivialHashtable ambiguousTypes, TrivialHashtable referencedLabels)
   : base(errorHandler) {
   this.typeSystem = typeSystem;
   this.Errors = errorHandler == null ? null : errorHandler.Errors;
   this.scopeFor = scopeFor;
   this.ambiguousTypes = ambiguousTypes;
   this.referencedLabels = referencedLabels;
   this.MayNotReferenceThisFromFieldInitializer = true;
   this.allowedExceptions = new TypeNodeList();
   this.useGenerics = TargetPlatform.UseGenerics;
   this.AllowPropertiesIndexersAsRef = true;
 }
Пример #15
0
        /// <summary>
        /// This is used to build the catalog of types in the parsed assemblies
        /// </summary>
        /// <param name="types">The list of types from an assembly</param>
        private void StoreTypes(TypeNodeList types)
        {
            for (int i = 0; i < types.Count; i++)
            {
                this.StoreType(types[i]);

                if (this.Canceled)
                {
                    break;
                }
            }
        }
Пример #16
0
 public override TypeNodeList VisitTypeNodeList(TypeNodeList types){
   if (types == null) return null;
   for (int i = 0, n = types.Count; i < n; i++){
     TypeNode type = types[i]; if (type == null) continue;
     if (this.Line != int.MinValue){
       if (!type.SourceContext.Encloses(this.Line, this.Column)) continue;
     }else{
       if (!type.SourceContext.Encloses(this.SourceContext)) continue;
     }
     this.Visit(type);
     break;
   }
   return types;
 }
Пример #17
0
 internal static TypeNodeList GetTypeList(string typeList, IDebugContext context){
   TypeNodeList list = new TypeNodeList();
   int startIndex = typeList.LastIndexOf(".")+1;
   int endIndex;
   IDebugType typ;
   while((endIndex = typeList.IndexOf("Or", startIndex)) > 0){
     typ = context.GetType(typeList.Substring(startIndex, endIndex - startIndex));
     if (typ != null) list.Add(typ.CompilerType);
     startIndex = endIndex+2;
   }
   typ = context.GetType(typeList.Substring(startIndex));
   if (typ != null) list.Add(typ.CompilerType);
   return list;
 }
Пример #18
0
        /** <summary>Check for any exposed members in any of the types.
         * Returns true if the type has an exposed memeber filter and
         * it is matched. This is used to determine if the namespace
         * should be visited if the namespace and all types are set to
         * false for exposed, we still want to visit them if any members
         * are set to true.
         * </summary> */
        private bool NamespaceContainsExposedMembers(Namespace space)
        {
            TypeNodeList types = space.Types;

            for (int i = 0; i < types.Count; i++)
            {
                TypeNode type = types[i];

                if (HasExposedMembers(type))
                {
                    return(true);
                }
            }
            return(false);
        }
Пример #19
0
        /// <summary>
        /// This is used to visit a list of types
        /// </summary>
        /// <param name="types">The list of types to visit</param>
        protected virtual void VisitTypes(TypeNodeList types)
        {
            // Visit the types in sorted order
            foreach (TypeNode type in types.OrderBy(t => t.FullName))
            {
                if (filter.IsExposedType(type) || filter.HasExposedMembers(type))
                {
                    this.VisitType(type);
                }

                if (this.Canceled)
                {
                    break;
                }
            }
        }
Пример #20
0
        public void PopulateTypeList(TypeNodeList types, TypeNode t)
        {
            if (types == null || t == null)
            {
                Debug.Assert(false); return;
            }
            types.Add(t);
            MemberList members = t.Members;

            for (int i = 0, n = members == null ? 0 : members.Length; i < n; i++)
            {
                t = members[i] as TypeNode;
                if (t == null)
                {
                    continue;
                }
                this.PopulateTypeList(types, t);
            }
        }
Пример #21
0
        private static TypeNodeList CreateTemplateParameters(Class closureClass, Method @from, TypeNode declaringType)
        {
            var dup = new Duplicator(declaringType.DeclaringModule, declaringType);

            var templateParameters = new TypeNodeList();

            var parentCount = declaringType.ConsolidatedTemplateParameters.CountOrDefault();

            for (int i = 0; i < from.TemplateParameters.Count; i++)
            {
                var tp = HelperMethods.NewEqualTypeParameter(
                    dup, (ITypeParameter)from.TemplateParameters[i],
                    closureClass, parentCount + i);

                templateParameters.Add(tp);
            }

            return(templateParameters);
        }
Пример #22
0
 protected virtual void VisitTypes(TypeNodeList types)
 {
     // sort types by name
     TypeNode[] sorted_types = new TypeNode[types.Count];
     for (int i = 0; i < types.Count; i++)
     {
         sorted_types[i] = types[i];
     }
     Array.Sort <TypeNode>(sorted_types, typeComparison);
     // visit them
     foreach (TypeNode type in sorted_types)
     {
         //Console.WriteLine("visiting {0}", type.Name);
         //visit this type if it is exposed, or has members that are set as exposed
         if (filter.IsExposedType(type) || filter.HasExposedMembers(type))
         {
             VisitType(type); //visit type and members
         }
     }
 }
Пример #23
0
        private bool?NamespaceContainesExposedTypes(Namespace space)
        {
            TypeNodeList types = space.Types;

            for (int i = 0; i < types.Count; i++)
            {
                TypeNode type = types[i];
                if (IsExposedType(type))
                {
                    return(true);
                }
            }

            if (apiFilter.NamespaceFilterCount < 1)
            {
                return(null); //this apiFilter does not contain any namespaces
            }

            return(false);
        }
        public override void VisitTypeNodeList(TypeNodeList types)
        {
            if (types == null) return;

            for (int i = 0, n = types.Count; i < n; i++)
            {
                var type = types[i];
                if (type == null) continue;

                Class c = type as Class;
                if (c != null && HelperMethods.IsContractTypeForSomeOtherType(c))
                {
                    types[i] = null;
                }
                else
                {
                    // for nested types
                    this.VisitTypeNode(type);
                }
            }
        }
Пример #25
0
 public override TypeNodeList VisitTypeParameterList(TypeNodeList typeParameters)
 {
     typeParameters = base.VisitTypeParameterList(typeParameters);
     for (int i = 0, n = typeParameters == null ? 0 : typeParameters.Count; i < n; i++)
     {
         TypeNode tp = typeParameters[i];
         if (tp == null)
         {
             continue;
         }
         ClassParameter cp = tp as ClassParameter;
         if (cp != null)
         {
             if (cp.BaseClass == null)
             {
                 cp.BaseClass = this.VisitTypeReference(cp.BaseClassExpression) as Class;
             }
         }
         typeParameters[i] = base.VisitTypeParameter(tp);
     }
     return(typeParameters);
 }
Пример #26
0
        private static void WriteMethod(Method method, TextWriter writer)
        {
            string name = method.Name.Name;

            WriteType(method.DeclaringType, writer);
            writer.Write(".{0}", name);
            if (method.IsGeneric)
            {
                TypeNodeList genericParameters = method.TemplateParameters;
                if (genericParameters != null)
                {
                    writer.Write("``{0}", genericParameters.Count);
                }
            }
            WriteParameters(method.Parameters, writer);
            // add ~ for conversion operators
            if ((name == "op_Implicit") || (name == "op_Explicit"))
            {
                writer.Write("~");
                WriteType(method.ReturnType, writer);
            }
        }
Пример #27
0
        //----------------------------------------------------------------------

        private static TypeNodeList findAll(string name)
        {
            if (allNamespaces == null)
            {
                init();
            }
            TypeNodeList nsl = new TypeNodeList();

            nsCached.Add(name, nsl);
            for (int i = 0, n = allNamespaces.Length; i < n; i++)
            {
                if (allNamespaces[i].Name.Name == name)
                {
                    Namespace    ns   = allNamespaces[i];
                    TypeNodeList tnls = ns.Types;
                    for (int k = 0; k < tnls.Length; k++)
                    {
                        nsl.Add(tnls[k]);
                    }
                }
            }
            return(nsl);
        }
Пример #28
0
 public virtual TypeNodeList VisitTypeReferenceList(TypeNodeList typeReferences, TypeNodeList changes, TypeNodeList deletions, TypeNodeList insertions){
   if (typeReferences == null) return changes;
   if (changes != null){
     if (deletions == null || insertions == null)
       Debug.Assert(false);
     else{
     }
   }else if (deletions != null)
     return null;
   return typeReferences;
 }
Пример #29
0
        //=====================================================================

        /// <summary>
        /// This finds all extension methods, adds information about them to the types, and tracks
        /// them for adding to the reflection data later in the other callbacks.
        /// </summary>
        /// <param name="writer">The reflection data XML writer</param>
        /// <param name="info">For this callback, the information object is a namespace list</param>
        private void RecordExtensionMethods(XmlWriter writer, object info)
        {
            NamespaceList spaces = (NamespaceList)info;

            foreach (Namespace space in spaces)
            {
                // !EFW - Don't bother checking unexposed namespaces
                if (!mrw.ApiFilter.IsExposedNamespace(space))
                {
                    continue;
                }

                TypeNodeList types = space.Types;

                foreach (TypeNode type in types)
                {
                    // !EFW - Don't bother checking unexposed types
                    if (!mrw.ApiFilter.IsExposedType(type))
                    {
                        continue;
                    }

                    // Go through the members looking for fields signaling extension methods.  Members may be
                    // added so convert to a list first to avoid enumeration issues.
                    foreach (Member member in type.Members.ToList())
                    {
                        Method method = member as Method;

                        if (method == null || !mrw.ApiFilter.IsExposedMember(method) ||
                            !method.Attributes.Any(a => a.Type.FullName == "System.Runtime.CompilerServices.ExtensionAttribute"))
                        {
                            continue;
                        }

                        ParameterList parameters = method.Parameters;

                        // !EFW - This fix was reported without an example.  Sometimes, there are no parameters.
                        // In such cases, ignore it to prevent a crash.
                        if (parameters == null || parameters.Count == 0)
                        {
                            continue;
                        }

                        TypeNode extendedType = parameters[0].Type;

                        // Recognize generic extension methods where the extended type is a specialization of a
                        // generic type and the extended type's specialized template argument is a type parameter
                        // declared by the generic extension method.  In this case, we need to save a TypeNode
                        // for the non-specialized type in the index because a TypeNode for the specialized type
                        // won't match correctly in AddExtensionMethods().  NOTE: we are not interested in
                        // extended types that are specialized by a specific type rather than by the extension
                        // method's template parameter.
                        if (method.IsGeneric && method.TemplateParameters.Count > 0)
                        {
                            if (extendedType.IsGeneric && extendedType.TemplateArguments != null &&
                                extendedType.TemplateArguments.Count == 1)
                            {
                                // Is the extended type's template argument a template parameter rather than a
                                // specialized type?
                                TypeNode arg = extendedType.TemplateArguments[0];

                                if (arg.IsTemplateParameter)
                                {
                                    // Is the template parameter declared on the extension method
                                    ITypeParameter gtp = (ITypeParameter)arg;

                                    if (gtp.DeclaringMember == method && gtp.ParameterListIndex == 0)
                                    {
                                        // Get a TypeNode for the non-specialized type
                                        extendedType = extendedType.GetTemplateType();
                                    }
                                }
                            }
                        }

                        List <Method> methods = null;

                        if (!index.TryGetValue(extendedType, out methods))
                        {
                            methods = new List <Method>();
                            index.Add(extendedType, methods);
                        }

                        methods.Add(method);
                    }
                }
            }
        }
Пример #30
0
        /// <summary>
        /// This is used to visit a list of types
        /// </summary>
        /// <param name="types">The list of types to visit</param>
        protected virtual void VisitTypes(TypeNodeList types)
        {
            // Visit the types in sorted order
            foreach(TypeNode type in types.OrderBy(t => t.FullName))
            {
                if(filter.IsExposedType(type) || filter.HasExposedMembers(type))
                    this.VisitType(type);

                if(this.Canceled)
                    break;
            }
        }
Пример #31
0
        public EmitAsyncClosure(Method from, Rewriter rewriter)
        {
            Contract.Requires(from != null);
            Contract.Requires(from.DeclaringType != null);
            Contract.Requires(rewriter != null);

            if (TaskExtensionsTypeNode == null)
            {
                throw new InvalidOperationException(
                          "Can't generate async closure because System.Threading.Tasks.TaskExceptions class is unavailable.");
            }

            this.rewriter      = rewriter;
            this.declaringType = from.DeclaringType;

            var closureName = HelperMethods.NextUnusedMemberName(declaringType, "<" + from.Name.Name + ">AsyncContractClosure");

            this.closureClass = new Class(
                declaringModule: declaringType.DeclaringModule,
                declaringType: declaringType,
                attributes: null,
                flags: TypeFlags.NestedPrivate,
                Namespace: null,
                name: Identifier.For(closureName),
                baseClass: SystemTypes.Object,
                interfaces: null,
                members: null);

            declaringType.Members.Add(this.closureClass);
            RewriteHelper.TryAddCompilerGeneratedAttribute(this.closureClass);

            var taskType = from.ReturnType;

            this.aggregateExceptionType = new Cache <TypeNode>(() =>
                                                               HelperMethods.FindType(rewriter.AssemblyBeingRewritten, StandardIds.System,
                                                                                      Identifier.For("AggregateException")));

            this.func2Type = new Cache <TypeNode>(() =>
                                                  HelperMethods.FindType(SystemTypes.SystemAssembly, StandardIds.System, Identifier.For("Func`2")));

            if (from.IsGeneric)
            {
                this.closureClass.TemplateParameters = CreateTemplateParameters(closureClass, from, declaringType);

                this.closureClass.IsGeneric = true;
                this.closureClass.EnsureMangledName();

                this.forwarder = new Specializer(
                    targetModule: this.declaringType.DeclaringModule,
                    pars: from.TemplateParameters,
                    args: this.closureClass.TemplateParameters);

                this.forwarder.VisitTypeParameterList(this.closureClass.TemplateParameters);

                taskType = this.forwarder.VisitTypeReference(taskType);
            }
            else
            {
                this.closureClassInstance = this.closureClass;
            }

            this.checkMethodTaskType = taskType;

            // Emiting CheckPost method declaration
            EmitCheckPostMethodCore(checkMethodTaskType);

            // Generate closure constructor.
            // Constructor should be generated AFTER visiting type parameters in
            // the previous block of code. Otherwise current class would not have
            // appropriate number of generic arguments!
            var ctor = CreateConstructor(closureClass);

            closureClass.Members.Add(ctor);

            // Now that we added the ctor and the check method, let's instantiate the closure class if necessary
            if (this.closureClassInstance == null)
            {
                var consArgs = new TypeNodeList();
                var args     = new TypeNodeList();

                var parentCount = this.closureClass.DeclaringType.ConsolidatedTemplateParameters == null
                    ? 0
                    : this.closureClass.DeclaringType.ConsolidatedTemplateParameters.Count;

                for (int i = 0; i < parentCount; i++)
                {
                    consArgs.Add(this.closureClass.DeclaringType.ConsolidatedTemplateParameters[i]);
                }

                var methodCount = from.TemplateParameters == null ? 0 : from.TemplateParameters.Count;
                for (int i = 0; i < methodCount; i++)
                {
                    consArgs.Add(from.TemplateParameters[i]);
                    args.Add(from.TemplateParameters[i]);
                }

                this.closureClassInstance =
                    (Class)
                    this.closureClass.GetConsolidatedTemplateInstance(this.rewriter.AssemblyBeingRewritten,
                                                                      closureClass.DeclaringType, closureClass.DeclaringType, args, consArgs);
            }

            // create closure initializer for context method
            this.closureLocal       = new Local(this.ClosureClass);
            this.ClosureInitializer = new Block(new StatementList());

            // TODO: What is this?
            // Add ClosureLocal instantiation?
            this.ClosureInitializer.Statements.Add(
                new AssignmentStatement(
                    this.closureLocal,
                    new Construct(new MemberBinding(null, this.Ctor), new ExpressionList())));
        }
Пример #32
0
 public virtual Differences VisitTypeNodeList(TypeNodeList list1, TypeNodeList list2,
   out TypeNodeList changes, out TypeNodeList deletions, out TypeNodeList insertions){
   changes = list1 == null ? null : list1.Clone();
   deletions = list1 == null ? null : list1.Clone();
   insertions = list1 == null ? new TypeNodeList() : list1.Clone();
   //^ assert insertions != null;
   Differences differences = new Differences();
   //Compare definitions that have matching key attributes
   TrivialHashtable matchingPosFor = new TrivialHashtable();
   TrivialHashtable matchedNodes = new TrivialHashtable();
   for (int j = 0, n = list2 == null ? 0 : list2.Count; j < n; j++){
     //^ assert list2 != null;
     TypeNode nd2 = list2[j];
     if (nd2 == null || nd2.Name == null) continue;
     string fullName = nd2.FullName;
     if (fullName == null) continue;
     matchingPosFor[Identifier.For(fullName).UniqueIdKey] = j;
     insertions.Add(null);
   }
   for (int i = 0, n = list1 == null ? 0 : list1.Count; i < n; i++){
     //^ assert list1 != null && changes != null && deletions != null;
     TypeNode nd1 = list1[i];
     if (nd1 == null || nd1.Name == null) continue;
     string fullName = nd1.FullName;
     if (fullName == null) continue;
     object pos = matchingPosFor[Identifier.For(fullName).UniqueIdKey];
     if (!(pos is int)) continue;
     //^ assert pos != null;
     //^ assume list2 != null; //since there was entry int matchingPosFor
     int j = (int)pos;
     TypeNode nd2 = list2[j];
     //^ assume nd2 != null;
     //nd1 and nd2 have the same key attributes and are therefore treated as the same entity
     matchedNodes[nd1.UniqueKey] = nd1;
     matchedNodes[nd2.UniqueKey] = nd2;
     //nd1 and nd2 may still be different, though, so find out how different
     Differences diff = this.VisitTypeNode(nd1, nd2);
     if (diff == null){Debug.Assert(false); continue;}
     if (diff.NumberOfDifferences != 0){
       changes[i] = diff.Changes as TypeNode;
       deletions[i] = diff.Deletions as TypeNode;
       insertions[i] = diff.Insertions as TypeNode;
       insertions[n+j] = nd1; //Records the position of nd2 in list2 in case the change involved a permutation
       //Debug.Assert(diff.Changes == changes[i] && diff.Deletions == deletions[i] && diff.Insertions == insertions[i]);
       differences.NumberOfDifferences += diff.NumberOfDifferences;
       differences.NumberOfSimilarities += diff.NumberOfSimilarities;
       if (nd1.DeclaringModule == this.OriginalModule || 
         (nd1.DeclaringType != null && nd1.DeclaringType.DeclaringModule == this.OriginalModule)){
         if (this.MembersThatHaveChanged == null) this.MembersThatHaveChanged = new MemberList();
         this.MembersThatHaveChanged.Add(nd1);
       }
       continue;
     }
     changes[i] = null;
     deletions[i] = null;
     insertions[i] = null;
     insertions[n+j] = nd1; //Records the position of nd2 in list2 in case the change involved a permutation
   }
   //Find deletions
   for (int i = 0, n = list1 == null ? 0 : list1.Count; i < n; i++){
     //^ assert list1 != null && changes != null && deletions != null;
     TypeNode nd1 = list1[i]; 
     if (nd1 == null) continue;
     if (matchedNodes[nd1.UniqueKey] != null) continue;
     changes[i] = null;
     deletions[i] = nd1;
     insertions[i] = null;
     differences.NumberOfDifferences += 1;
     if (nd1.DeclaringModule == this.OriginalModule || 
       (nd1.DeclaringType != null && nd1.DeclaringType.DeclaringModule == this.OriginalModule)){
       if (this.MembersThatHaveChanged == null) this.MembersThatHaveChanged = new MemberList();
       this.MembersThatHaveChanged.Add(nd1);
     }
   }
   //Find insertions
   for (int j = 0, n = list1 == null ? 0 : list1.Count, m = list2 == null ? 0 : list2.Count; j < m; j++){
     //^ assert list2 != null;
     TypeNode nd2 = list2[j]; 
     if (nd2 == null) continue;
     if (matchedNodes[nd2.UniqueKey] != null) continue;
     insertions[n+j] = nd2;  //Records nd2 as an insertion into list1, along with its position in list2
     differences.NumberOfDifferences += 1; //REVIEW: put the size of the tree here?
   }
   if (differences.NumberOfDifferences == 0){
     changes = null;
     deletions = null;
     insertions = null;
   }
   return differences;
 }
Пример #33
0
 public override TypeNodeList VisitTypeParameterList(TypeNodeList typeParameters) {
   typeParameters = base.VisitTypeParameterList(typeParameters);
   for (int i = 0, n = typeParameters == null ? 0 : typeParameters.Count; i < n; i++) {
     TypeNode tp = typeParameters[i];
     if (tp == null) continue;
     ClassParameter cp = tp as ClassParameter;
     if (cp != null) {
       if (cp.BaseClass == null) cp.BaseClass = this.VisitTypeReference(cp.BaseClassExpression) as Class;
     }
     typeParameters[i] = base.VisitTypeParameter(tp);
   }
   return typeParameters;
 }
Пример #34
0
 public virtual TypeNodeList VisitTypeNodeList(TypeNodeList types)
 {
     if (types == null) return null;
     for (int i = 0; i < types.Count; i++) //Visiting a type may result in a new type being appended to this list
         types[i] = (TypeNode)this.Visit(types[i]);
     return types;
 }
Пример #35
0
        private static void TransformOriginalConsolidatedTypeFormalsIntoMethodFormals(Method dupMethod,
            Method closureMethod, Method closureInstanceMethod, out TypeNodeList actuals)
        {
            // make sure that if we copy it from a generic context, the method becomes generic in the target context
            // if we are copying from the same declaring type (not instantiated), then don't add enclosing type parameters.
            var originals = closureInstanceMethod.DeclaringType.ConsolidatedTemplateArguments == null
                ? null
                : closureMethod.DeclaringType.ConsolidatedTemplateParameters;

            if (originals != null)
            {
                originals = originals.Clone();
            }
            
            if (closureMethod.TemplateParameters != null && closureMethod.TemplateParameters.Count > 0)
            {
                if (originals == null)
                {
                    originals = closureMethod.TemplateParameters.Clone();
                }
                else
                {
                    foreach (var tp in closureMethod.TemplateParameters)
                    {
                        originals.Add(tp);
                    }
                }
            }

            if (originals == null)
            {
                actuals = null;
                return;
            }

            actuals = closureInstanceMethod.DeclaringType.ConsolidatedTemplateArguments == null
                ? null
                : closureInstanceMethod.DeclaringType.ConsolidatedTemplateArguments.Clone();
            
            if (closureInstanceMethod.TemplateArguments != null && closureInstanceMethod.TemplateArguments.Count > 0)
            {
                if (actuals == null)
                {
                    actuals = closureInstanceMethod.TemplateArguments.Clone();
                }
                else
                {
                    foreach (var tp in closureInstanceMethod.TemplateArguments)
                    {
                        actuals.Add(tp);
                    }
                }
            }

            var declaringModule = dupMethod.DeclaringType.DeclaringModule;

            // new method formals
            var tparams = originals.Clone();

            for (int i = 0; i < originals.Count; i++)
            {
                // setup forwarding of tparams to method params
                ITypeParameter tp = originals[i] as ITypeParameter;
                
                TypeNode mtp = NewEqualMethodTypeParameter(tp, dupMethod, i);
                
                tparams[i] = mtp;
            }

            var specializer = new Specializer(declaringModule, originals, tparams);
            
            // System.Console.WriteLine("Made {0} a generic method", dupMethod.FullName);
            dupMethod.TemplateParameters = tparams;
            dupMethod.IsGeneric = true;

            specializer.VisitMethod(dupMethod);
            
            var bodySpecializer = new MethodBodySpecializer(declaringModule, originals, tparams);
            
            bodySpecializer.CurrentType = dupMethod.DeclaringType;
            bodySpecializer.CurrentMethod = dupMethod;
            bodySpecializer.VisitBlock(dupMethod.Body);
        }
Пример #36
0
 public static bool IsNullOrEmpty(this TypeNodeList list)
 {
     return(list == null || list.Count == 0);
 }
Пример #37
0
 // TODO: retire this method ater moving to C# 6.0
 public static int CountOrDefault(this TypeNodeList list)
 {
     return(list == null ? 0 : list.Count);
 }
Пример #38
0
 public virtual void VisitResolvedTypeReferenceList(TypeNodeList resolvedTypeList, TypeNodeList typeExpressionList){
   if (resolvedTypeList == null || typeExpressionList == null) return;
   int n = resolvedTypeList.Count;
   if (n > typeExpressionList.Count){Debug.Assert(false); n = typeExpressionList.Count;}
   for (int i = 0; i < n; i++){
     TypeNode resolvedType = resolvedTypeList[i];
     if (resolvedType == null) continue;
     TypeNode reference = typeExpressionList[i];
     if (reference == null) continue;
     this.VisitResolvedTypeReference(resolvedType, reference);
   }
 }
Пример #39
0
 public override Expression VisitConstructArray(ConstructArray consArr){
   if (consArr == null) return consArr;
   TypeNode et = consArr.ElementType = this.VisitTypeReference(consArr.ElementType);
   ExpressionList dims = consArr.Operands = this.VisitExpressionList(consArr.Operands);
   consArr.Initializers = this.VisitExpressionList(consArr.Initializers);
   if (et == null && consArr.ElementTypeExpression == null) {
     TypeNodeList tl = new TypeNodeList();
     for (int i = 0, n = consArr.Initializers == null ? 0 : consArr.Initializers.Count; i < n; i++) {
       Expression e = consArr.Initializers[i];
       if (e == null || e.Type == null) continue;
       Literal lit = e as Literal;
       if (lit != null && lit.Value == null) continue; //This prevents null from participating in the type unification, which is by design.
       if (e.Type == null) continue; //e is a bad expression
       tl.Add(e.Type);
     }
     et = this.typeSystem.UnifiedType(tl, this.TypeViewer);
     if (et == null) et = SystemTypes.Object;
     consArr.ElementType = et;
   }
   if (et is DelegateNode) {
     for (int i = 0, n = consArr.Initializers == null ? 0 : consArr.Initializers.Count; i < n; i++) {
       Expression e = consArr.Initializers[i];
       if (e is MemberBinding && ((MemberBinding)e).BoundMember is Method)
         consArr.Initializers[i] = this.VisitExpression(new Construct(new MemberBinding(null, et), new ExpressionList(e)));
     }
   }
   consArr.Owner = this.VisitExpression(consArr.Owner);
   consArr.Type = SystemTypes.Object;
   if (et == null) return null;
   consArr.Type = et.GetArrayType(consArr.Rank);
   if (this.currentPreprocessorDefinedSymbols != null && this.NonNullChecking)
     consArr.Type = OptionalModifier.For(SystemTypes.NonNullType, consArr.Type);
   return consArr;
 }
Пример #40
0
    /// <summary>
    /// If type has an explicit or implicit implementation of a method that has an out-of-band contract,
    /// then need to create a proxy that has the same signature as the "real" interface
    /// method and have it call the one the programmer wrote.
    /// </summary>
    /// <param name="type">The type whose members should be checked to find such methods.</param>
    public virtual void CheckForInterfaceImplementationsOfOutOfBandContractedMethods(TypeNode type) {
      MemberList members = this.GetTypeView(type).Members;  // do we need to check all methods?
      for (int i = 0, n = members == null ? 0 : members.Count; i < n; i++) {
        Method method = members[i] as Method;
        if (method == null) continue;

        // If a method is a proxy (created in CheckAbstractMethods), then it can be ignored.
        ProxyMethod pMethod = method as ProxyMethod;
        if (pMethod != null) continue;

        #region Implicit implementation
        // If the method isn't virtual, then it will have been given a proxy as part of CheckAbstractMethods
        if (method.IsVirtual && method.ImplicitlyImplementedInterfaceMethods != null) {
          MethodList remainingImplicitImplementedInterfaceMethods = new MethodList(method.ImplicitlyImplementedInterfaceMethods.Count);
          for (int j = 0, m = method.ImplicitlyImplementedInterfaceMethods.Count; j < m; j++) {
            Method ifaceMethod = method.ImplicitlyImplementedInterfaceMethods[j];
            if (ifaceMethod != null && ifaceMethod.HasOutOfBandContract) {
              this.CreateProxy(type, ifaceMethod, method);
            } else {
              remainingImplicitImplementedInterfaceMethods.Add(ifaceMethod);
            }
          }
          method.ImplicitlyImplementedInterfaceMethods = remainingImplicitImplementedInterfaceMethods;
        }
        #endregion Implicit implementation

        #region Explicit implementation
        if (method.ImplementedInterfaceMethods != null) {
          MethodList remainingImplementedInterfaceMethods = new MethodList(method.ImplementedInterfaceMethods.Count);
          TypeNodeList remainingImplementedTypes = new TypeNodeList(method.ImplementedTypes.Count);
          for (int j = 0, m = method.ImplementedInterfaceMethods.Count; j < m; j++) {
            Method ifaceMethod = method.ImplementedInterfaceMethods[j];
            TypeNode ifaceType = method.ImplementedTypes[j];
            if (ifaceMethod != null && ifaceMethod.HasOutOfBandContract) {
              this.CreateProxy(type, ifaceMethod, method);
              // We may need to modify the name if there is another method
              // in the type that has the same name. That is, method's name
              // was written by the programmer as I.f where I is the name of
              // the interface. But since it no longer implements the interface
              // (the proxy does instead), its name will be just "f" in the
              // assembly. If there is another method in the same type with
              // that name, the IL will be bad. So just to play it safe, make
              // the name "fully qualified", i.e., I.f.
              method.Name = new Identifier(ifaceMethod.FullName, method.Name.SourceContext);
            } else {
              remainingImplementedInterfaceMethods.Add(ifaceMethod);
              remainingImplementedTypes.Add(ifaceType);
            }
          }
          method.ImplementedInterfaceMethods = remainingImplementedInterfaceMethods;
          method.ImplementedTypes = remainingImplementedTypes;
        }
        #endregion Explicit implementation
      }
    }
Пример #41
0
        public override TypeNode VisitTypeReference(TypeNode type)
        { //TODO: break up this method
            if (type == null) return null;
            TypeNodeList pars = this.pars;
            TypeNodeList args = this.args;
            switch (type.NodeType)
            {
                case NodeType.ArrayType:
                    ArrayType arrType = (ArrayType)type;
                    TypeNode elemType = this.VisitTypeReference(arrType.ElementType);
                    if (elemType == arrType.ElementType || elemType == null) return arrType;
                    if (arrType.IsSzArray()) return elemType.GetArrayType(1);
                    return elemType.GetArrayType(arrType.Rank, arrType.Sizes, arrType.LowerBounds);

                case NodeType.DelegateNode:
                    {
                        FunctionType ftype = type as FunctionType;
                        if (ftype == null) goto default;
                        TypeNode referringType = ftype.DeclaringType == null ? this.CurrentType : this.VisitTypeReference(ftype.DeclaringType);
                        return FunctionType.For(this.VisitTypeReference(ftype.ReturnType), this.VisitParameterList(ftype.Parameters), referringType);
                    }

                case NodeType.Pointer:
                    Pointer pType = (Pointer)type;
                    elemType = this.VisitTypeReference(pType.ElementType);
                    if (elemType == pType.ElementType || elemType == null) return pType;
                    return elemType.GetPointerType();
                case NodeType.Reference:
                    Reference rType = (Reference)type;
                    elemType = this.VisitTypeReference(rType.ElementType);
                    if (elemType == rType.ElementType || elemType == null) return rType;
                    return elemType.GetReferenceType();

                case NodeType.ArrayTypeExpression:
                    ArrayTypeExpression aExpr = (ArrayTypeExpression)type;
                    aExpr.ElementType = this.VisitTypeReference(aExpr.ElementType);
                    return aExpr;
                case NodeType.BoxedTypeExpression:
                    BoxedTypeExpression bExpr = (BoxedTypeExpression)type;
                    bExpr.ElementType = this.VisitTypeReference(bExpr.ElementType);
                    return bExpr;
                case NodeType.ClassExpression:
                    {
                        ClassExpression cExpr = (ClassExpression)type;
                        cExpr.Expression = this.VisitTypeExpression(cExpr.Expression);
                        Literal lit = cExpr.Expression as Literal; //Could happen if the expression is a template parameter
                        if (lit != null) return lit.Value as TypeNode;
                        cExpr.TemplateArguments = this.VisitTypeReferenceList(cExpr.TemplateArguments);
                        return cExpr;
                    }

                case NodeType.ClassParameter:
                case NodeType.TypeParameter:
                    int key = type.UniqueKey;
                    for (int i = 0, n = pars == null ? 0 : pars.Count, m = args == null ? 0 : args.Count; i < n && i < m; i++)
                    {
                        //^ assert pars != null && args != null;
                        TypeNode tp = pars[i];
                        if (tp == null) continue;
                        if (tp.UniqueKey == key) return args[i];
                        if (tp.Name.UniqueIdKey == type.Name.UniqueIdKey && (tp is ClassParameter && type is TypeParameter))
                        {
                            //This shouldn't really happen, but in practice it does. Hack past it.
                            return args[i];
                        }
                    }
                    return type;

                case NodeType.FlexArrayTypeExpression:
                    FlexArrayTypeExpression flExpr = (FlexArrayTypeExpression)type;
                    flExpr.ElementType = this.VisitTypeReference(flExpr.ElementType);
                    return flExpr;
                case NodeType.FunctionTypeExpression:
                    FunctionTypeExpression ftExpr = (FunctionTypeExpression)type;
                    ftExpr.Parameters = this.VisitParameterList(ftExpr.Parameters);
                    ftExpr.ReturnType = this.VisitTypeReference(ftExpr.ReturnType);
                    return ftExpr;
                case NodeType.InvariantTypeExpression:
                    InvariantTypeExpression invExpr = (InvariantTypeExpression)type;
                    invExpr.ElementType = this.VisitTypeReference(invExpr.ElementType);
                    return invExpr;

                case NodeType.InterfaceExpression:
                    InterfaceExpression iExpr = (InterfaceExpression)type;
                    if (iExpr.Expression == null) goto default;
                    iExpr.Expression = this.VisitTypeExpression(iExpr.Expression);
                    iExpr.TemplateArguments = this.VisitTypeReferenceList(iExpr.TemplateArguments);
                    return iExpr;

                case NodeType.NonEmptyStreamTypeExpression:
                    NonEmptyStreamTypeExpression neExpr = (NonEmptyStreamTypeExpression)type;
                    neExpr.ElementType = this.VisitTypeReference(neExpr.ElementType);
                    return neExpr;
                case NodeType.NonNullTypeExpression:
                    NonNullTypeExpression nnExpr = (NonNullTypeExpression)type;
                    nnExpr.ElementType = this.VisitTypeReference(nnExpr.ElementType);
                    return nnExpr;
                case NodeType.NonNullableTypeExpression:
                    NonNullableTypeExpression nbExpr = (NonNullableTypeExpression)type;
                    nbExpr.ElementType = this.VisitTypeReference(nbExpr.ElementType);
                    return nbExpr;
                case NodeType.NullableTypeExpression:
                    NullableTypeExpression nuExpr = (NullableTypeExpression)type;
                    nuExpr.ElementType = this.VisitTypeReference(nuExpr.ElementType);
                    return nuExpr;

                case NodeType.OptionalModifier:
                    {
                        TypeModifier modType = (TypeModifier)type;
                        TypeNode modifiedType = this.VisitTypeReference(modType.ModifiedType);
                        TypeNode modifierType = this.VisitTypeReference(modType.Modifier);
                        if (modifiedType == null || modifierType == null) { return type; }

                        return OptionalModifier.For(modifierType, modifiedType);
                    }
                case NodeType.RequiredModifier:
                    {
                        TypeModifier modType = (TypeModifier)type;
                        TypeNode modifiedType = this.VisitTypeReference(modType.ModifiedType);
                        TypeNode modifierType = this.VisitTypeReference(modType.Modifier);
                        if (modifiedType == null || modifierType == null) { Debug.Fail(""); return type; }
                        return RequiredModifier.For(modifierType, modifiedType);
                    }

                case NodeType.OptionalModifierTypeExpression:
                    OptionalModifierTypeExpression optmodType = (OptionalModifierTypeExpression)type;
                    optmodType.ModifiedType = this.VisitTypeReference(optmodType.ModifiedType);
                    optmodType.Modifier = this.VisitTypeReference(optmodType.Modifier);
                    return optmodType;
                case NodeType.RequiredModifierTypeExpression:
                    RequiredModifierTypeExpression reqmodType = (RequiredModifierTypeExpression)type;
                    reqmodType.ModifiedType = this.VisitTypeReference(reqmodType.ModifiedType);
                    reqmodType.Modifier = this.VisitTypeReference(reqmodType.Modifier);
                    return reqmodType;
                case NodeType.PointerTypeExpression:
                    PointerTypeExpression pExpr = (PointerTypeExpression)type;
                    pExpr.ElementType = this.VisitTypeReference(pExpr.ElementType);
                    return pExpr;
                case NodeType.ReferenceTypeExpression:
                    ReferenceTypeExpression rExpr = (ReferenceTypeExpression)type;
                    rExpr.ElementType = this.VisitTypeReference(rExpr.ElementType);
                    return rExpr;
                case NodeType.StreamTypeExpression:
                    StreamTypeExpression sExpr = (StreamTypeExpression)type;
                    sExpr.ElementType = this.VisitTypeReference(sExpr.ElementType);
                    return sExpr;
                case NodeType.TupleTypeExpression:
                    TupleTypeExpression tuExpr = (TupleTypeExpression)type;
                    tuExpr.Domains = this.VisitFieldList(tuExpr.Domains);
                    return tuExpr;
                case NodeType.TypeExpression:
                    {
                        TypeExpression tExpr = (TypeExpression)type;
                        tExpr.Expression = this.VisitTypeExpression(tExpr.Expression);
                        if (tExpr.Expression is Literal) return type;
                        tExpr.TemplateArguments = this.VisitTypeReferenceList(tExpr.TemplateArguments);
                        return tExpr;
                    }
                case NodeType.TypeIntersectionExpression:
                    TypeIntersectionExpression tiExpr = (TypeIntersectionExpression)type;
                    tiExpr.Types = this.VisitTypeReferenceList(tiExpr.Types);
                    return tiExpr;
                case NodeType.TypeUnionExpression:
                    TypeUnionExpression tyuExpr = (TypeUnionExpression)type;
                    tyuExpr.Types = this.VisitTypeReferenceList(tyuExpr.Types);
                    return tyuExpr;

                default:
                    TypeNode declaringType = this.VisitTypeReference(type.DeclaringType);
                    if (declaringType != null)
                    {
                        Identifier tname = type.Name;
                        if (type.Template != null && type.IsGeneric) tname = type.Template.Name;
                        TypeNode nt = declaringType.GetNestedType(tname);
                        if (nt != null)
                        {
                            TypeNodeList arguments = type.TemplateArguments;
                            type = nt;
                            if (TargetPlatform.UseGenerics)
                            {
                                if (arguments != null && arguments.Count > 0 && nt.ConsolidatedTemplateParameters != null && nt.ConsolidatedTemplateParameters.Count > 0)
                                    type = nt.GetTemplateInstance(this.TargetModule, this.CurrentType, declaringType, arguments);
                            }
                        }
                    }

                    if(type.Template != null && (type.ConsolidatedTemplateParameters == null || type.ConsolidatedTemplateParameters.Count == 0))
                    {
                        if(!type.IsNotFullySpecialized && (!type.IsNormalized ||
                         (this.CurrentType != null && type.DeclaringModule == this.CurrentType.DeclaringModule)))
                        {
                            return type;
                        }

                        // Type is a template instance, but some of its arguments were themselves parameters.
                        // See if any of these parameters are to be specialized by this specializer.
                        bool mustSpecializeFurther = false;
                        TypeNodeList targs = type.TemplateArguments;
                        int numArgs = targs == null ? 0 : targs.Count;

                        if(targs != null)
                        {
                            targs = new TypeNodeList(targs);

                            for(int i = 0; i < numArgs; i++)
                            {
                                TypeNode targ = targs[i];
                                ITypeParameter tparg = targ as ITypeParameter;

                                if(tparg != null)
                                {
                                    for(int j = 0, np = pars == null ? 0 : pars.Count, m = args == null ? 0 : args.Count; j < np && j < m; j++)
                                    {
                                        //^ assert pars != null && args != null;
                                        if(TargetPlatform.UseGenerics)
                                        {
                                            ITypeParameter par = pars[j] as ITypeParameter;

                                            if(par == null)
                                                continue;

                                            if(tparg == par || (tparg.ParameterListIndex == par.ParameterListIndex && tparg.DeclaringMember == par.DeclaringMember))
                                            {
                                                targ = this.args[j];
                                                break;
                                            }
                                        }
                                        else
                                        {
                                            if(targ == pars[j])
                                            {
                                                targ = this.args[j];
                                                break;
                                            }
                                        }
                                    }
                                }
                                else
                                {
                                    if(targ != type)
                                        targ = this.VisitTypeReference(targ);

                                    if(targ == type)
                                        continue;
                                }

                                mustSpecializeFurther |= targs[i] != targ;
                                targs[i] = targ;
                            }
                        }

                        if(targs == null || !mustSpecializeFurther)
                            return type;

                        return type.Template.GetTemplateInstance(this.TargetModule, this.CurrentType, declaringType, targs);
                    }

                    TypeNodeList tPars = type.TemplateParameters;
                    if (tPars == null || tPars.Count == 0) return type; //Not a parameterized type. No need to get an instance.
                    TypeNodeList tArgs = new TypeNodeList();
                    for (int i = 0, n = tPars.Count; i < n; i++)
                    {
                        TypeNode tPar = tPars[i];
                        tArgs.Add(tPar); //Leave parameter in place if there is no match
                        if (tPar == null || tPar.Name == null) continue;
                        int idKey = tPar.Name.UniqueIdKey;
                        for (int j = 0, m = pars == null ? 0 : pars.Count, k = args == null ? 0 : args.Count; j < m && j < k; j++)
                        {
                            //^ assert pars != null && args != null;
                            TypeNode par = pars[j];
                            if (par == null || par.Name == null) continue;
                            if (par.Name.UniqueIdKey == idKey)
                            {
                                tArgs[i] = args[j];
                                break;
                            }
                        }
                    }
                    return type.GetTemplateInstance(this.TargetModule, this.CurrentType, this.VisitTypeReference(type.DeclaringType), tArgs);
            }
        }
Пример #42
0
 public virtual TypeNodeList VisitTypeParameterList(TypeNodeList typeParameters)
 {
     if (typeParameters == null) return null;
     for (int i = 0, n = typeParameters.Count; i < n; i++)
         typeParameters[i] = this.VisitTypeParameter(typeParameters[i]);
     return typeParameters;
 }
Пример #43
0
    public override Method VisitMethod(Method method) {
      if (method == null) return null;
      if (method.IsNormalized) return method;
      this.MayReferenceThisAndBase = !(method is InstanceInitializer) || method.DeclaringType == null || method.DeclaringType.IsValueType;
      if (method.Name != null && method.Name.UniqueIdKey == StandardIds.Finalize.UniqueIdKey && method.HasCompilerGeneratedSignature &&
        method.DeclaringType is Class && ((Class)method.DeclaringType).IsAbstractSealedContainerForStatics)
        this.HandleError(method.Name, Error.DestructorInAbstractSealedClass);
      method.Attributes = this.VisitAttributeList(method.Attributes, method);
      method.ReturnAttributes = this.VisitAttributeList(method.ReturnAttributes);
      method.SecurityAttributes = this.VisitSecurityAttributeList(method.SecurityAttributes);
      if ((method.ReturnType == SystemTypes.DynamicallyTypedReference || method.ReturnType == SystemTypes.ArgIterator) && 
      (this.currentOptions == null || !this.currentOptions.NoStandardLibrary) ) {
        this.HandleError(method.Name, Error.CannotReturnTypedReference, this.GetTypeName(method.ReturnType));
        method.ReturnType = SystemTypes.Object;
      }
      if (method.Body != null) {
        if (method.DeclaringType is Interface && !method.IsStatic) {
          this.HandleError(method.Name, Error.InterfaceMemberHasBody, this.GetMethodSignature(method));
          method.Body = null;
        } else if (method.IsAbstract) {
          this.HandleError(method.Name, Error.AbstractHasBody, this.GetMethodSignature(method));
          method.Body = null;
        }
      } else if (!method.IsAbstract && !method.IsExtern && !this.isCompilingAContractAssembly) {
        this.HandleError(method.Name, Error.ConcreteMissingBody, this.GetMethodSignature(method));
        return null;
      } else if (method.TemplateParameters != null && method.TemplateParameters.Count > 0 && !this.useGenerics) {
        SourceContext ctx = method.TemplateParameters[0].SourceContext;
        ctx.EndPos = method.TemplateParameters[method.TemplateParameters.Count-1].SourceContext.EndPos;
        Debug.Assert(ctx.EndPos >= ctx.StartPos);
        Node n = new UnaryExpression();
        n.SourceContext = ctx;
        if (method.DeclaringType is Interface)
          this.HandleError(n, Error.AbstractInterfaceMethod);
        else
          this.HandleError(n, Error.AbstractMethodTemplate);
        return null;
      }
      BlockScope savedCurrentFinallyClause = this.currentFinallyClause;
      Method savedCurrentMethod = this.currentMethod;
      Return savedReturnNode = this.returnNode;
      Yield savedYieldNode = this.yieldNode;
      this.currentFinallyClause = null;
      this.currentMethod = method;
      this.returnNode = null;
      this.yieldNode = null;
      MethodScope scope = method.Scope;
      this.CheckForDuplicateDeclarations(scope);

      if ((this.currentPreprocessorDefinedSymbols != null && this.currentPreprocessorDefinedSymbols.ContainsKey("DefaultExposeBlocks")) &&
        !method.IsStatic && !(method is InstanceInitializer) && method.DeclaringType is Class && 
        !method.IsAbstract && method.CciKind == CciMemberKind.Regular && method.ApplyDefaultContract) {
        This thisOb = method.ThisParameter;
        MethodCall thisIsExposable = new MethodCall(
          new MemberBinding(null, SystemTypes.Guard.GetMethod(Identifier.For("FrameIsExposable"),
            SystemTypes.Object, SystemTypes.Type)),
            new ExpressionList(thisOb, new UnaryExpression(new Literal(method.DeclaringType, SystemTypes.Type),
            NodeType.Typeof, OptionalModifier.For(SystemTypes.NonNullType, SystemTypes.Type))), NodeType.Call,
            SystemTypes.Boolean, method.Body.SourceContext);
        Assumption assumption = new Assumption(thisIsExposable);
        Expose expose = new Expose(NodeType.Write);
        expose.SourceContext = method.Body.SourceContext;
        expose.Instance = thisOb;
        expose.Body = method.Body;
        if (this.currentOptions != null && this.currentOptions.DisableGuardedClassesChecks)
          method.Body = new Block(new StatementList(assumption, expose));
        else
          method.Body = new Block(new StatementList(expose));
      }


      #region Check contract rules for all interface methods and base methods this method implements/overrides
      bool ok = true;
      if (method.IsVirtual && !method.IsCompilerControlled) {
        // use FindNearest..., can't rely on method.OverriddenMethod since it might not be set further up the chain
        Method overridden = method.DeclaringType.FindNearestOverriddenMethod(method);
        if (overridden != null) {
          ok &= this.CheckContractRules(overridden, method, method.DeclaringType);
        }
        for (int i = 0, n = method.ImplementedInterfaceMethods == null ? 0 : method.ImplementedInterfaceMethods.Count; i < n; i++) {
          Method ifaceMethod = method.ImplementedInterfaceMethods[i];
          ok &= this.CheckContractRules(ifaceMethod, method, method.DeclaringType);
        }
        for (int i = 0, n = method.ImplicitlyImplementedInterfaceMethods == null ? 0 : method.ImplicitlyImplementedInterfaceMethods.Count; i < n; i++) {
          Method ifaceMethod = method.ImplicitlyImplementedInterfaceMethods[i];
          ok &= this.CheckContractRules(ifaceMethod, method, method.DeclaringType);
        }
      }
      #endregion

      #region Contract Inheritance for method overrides and interface implementations (do this somewhere else?)
      // This needs to be done here (and not in VisitMethodContract) because method might not even have a contract
      if (method.IsVirtual && ok && !method.IsCompilerControlled) {
        // use FindNearest..., can't rely on method.OverriddenMethod since it might not be set further up the chain
        Method overridden = method.DeclaringType.FindNearestOverriddenMethod(method);
        // FindNearestOverriddenMethod doesn't care if method is "new" or an "override", so explicity test IsVirtual property
        MethodContract cumulativeContract = method.Contract == null ? new MethodContract(method) : method.Contract;
        bool somethingWasCopied = false;
        while (overridden != null && overridden.IsVirtual) {
          if (overridden.Contract != null) {
            cumulativeContract.CopyFrom(overridden.Contract);
            somethingWasCopied = true;
            break;
          }
          overridden = overridden.DeclaringType.FindNearestOverriddenMethod(overridden);
        }
        // Can inherit from at most one interface method
        bool ifaceContractWasCopied = false;
        for (int i = 0, n = method.ImplementedInterfaceMethods == null ? 0 : method.ImplementedInterfaceMethods.Count; i < n; i++) {
          Method ifaceMethod = method.ImplementedInterfaceMethods[i];
          if (ifaceMethod == null) continue;
          if (ifaceMethod.Contract != null) {
            if (ifaceContractWasCopied) {
              this.HandleError(method, Error.RequiresNotAllowedInInterfaceImplementation, this.GetMethodSignature(ifaceMethod));
              break;
            }
            cumulativeContract.CopyFrom(ifaceMethod.Contract);
            somethingWasCopied = true;
            ifaceContractWasCopied = true;
          }
        }
        for (int i = 0, n = method.ImplicitlyImplementedInterfaceMethods == null ? 0 : method.ImplicitlyImplementedInterfaceMethods.Count; i < n; i++) {
          Method ifaceMethod = method.ImplicitlyImplementedInterfaceMethods[i];
          if (ifaceMethod == null) continue;
          if (ifaceMethod.Contract != null) {
            if (ifaceContractWasCopied) {
              this.HandleError(method, Error.RequiresNotAllowedInInterfaceImplementation, this.GetMethodSignature(ifaceMethod));
              break;
            }
            cumulativeContract.CopyFrom(ifaceMethod.Contract);
            somethingWasCopied = true;
            ifaceContractWasCopied = true;
          }
        }
        if (method.Contract == null && somethingWasCopied) { // otherwise it was already copied into the method's contract 
          method.Contract = cumulativeContract;
        }
      }
      #endregion
      
      // For checked exceptions, the actual exceptions thrown must be a subset of the allowed exceptions
      TypeNodeList aes = new TypeNodeList();
      if (method.Contract != null && method.Contract.Ensures != null) {
        for (int i = 0, n = method.Contract.Ensures.Count; i < n; i++) {
          EnsuresExceptional ee = method.Contract.Ensures[i] as EnsuresExceptional;
          if (ee == null || ee.Inherited) continue;
          aes.Add(ee.Type);
        }
      }
      TypeNodeList saveAllowedExceptions = this.allowedExceptions;
      this.allowedExceptions = aes;
      // don't check method body of proxy methods.
      Method result = (method is ProxyMethod) ? method : base.VisitMethod(method);
      this.allowedExceptions = saveAllowedExceptions;


      if (this.yieldNode != null && TypeNode.StripModifiers(method.ReturnType) is Interface) {
        StatementList statements = new StatementList(1);
        TypeNode elementType = SystemTypes.Object;
        Interface stype = (Interface)TypeNode.StripModifiers(method.ReturnType);
        if (stype.TemplateArguments != null && stype.TemplateArguments.Count == 1) elementType = stype.TemplateArguments[0];
        Class state = scope.ClosureClass;
        elementType = scope.FixTypeReference(elementType);
        state.Flags |= TypeFlags.Abstract; //So that no complaints are given about missing methods added by Normalizer
        state.Interfaces = new InterfaceList(5);
        state.Interfaces.Add(SystemTypes.IEnumerable);
        state.Interfaces.Add((Interface)SystemTypes.GenericIEnumerator.GetTemplateInstance(this.currentType, elementType));
        state.Interfaces.Add(SystemTypes.IEnumerator);
        state.Interfaces.Add(SystemTypes.IDisposable);
        state.Interfaces.Add((Interface)SystemTypes.GenericIEnumerable.GetTemplateInstance(this.currentType, elementType));
        //Add these methods so that Normalizer can find them even when reference to iterator is forward
        Method moveNext = new Method(state, null, StandardIds.MoveNext, null, SystemTypes.Boolean, null);
        moveNext.CallingConvention = CallingConventionFlags.HasThis;
        moveNext.Flags = MethodFlags.Public|MethodFlags.Virtual;
        moveNext.Body = new Block(new StatementList());
        state.Members.Add(moveNext);
        Method getCurrent = new Method(state, null, StandardIds.getCurrent, null, elementType, null);
        getCurrent.CallingConvention = CallingConventionFlags.HasThis;
        getCurrent.Flags = MethodFlags.Public|MethodFlags.Virtual|MethodFlags.SpecialName;
        getCurrent.Body = new Block(new StatementList());
        state.Members.Add(getCurrent);
        Return ret = new Return(new ConstructIterator(state, method.Body, elementType, state));
        if (method.Name.SourceContext.Document != null) {
          ret.SourceContext = method.SourceContext;
          ret.SourceContext.EndPos = method.Name.SourceContext.EndPos;
          Debug.Assert(ret.SourceContext.EndPos >= ret.SourceContext.StartPos);
        }
        statements.Add(ret);
        method.Body = new Block(statements);
        method.Body.Scope = new BlockScope(scope, method.Body);
      }
      if (method.IsStatic && method.IsVirtual && !method.IsSpecialName) {
        method.Flags &= ~MethodFlags.Static;
        this.HandleError(method.Name, Error.StaticNotVirtual, this.GetMethodSignature(method));
      }
      if (!method.OverridesBaseClassMember) {
        if (method.NodeType == NodeType.InstanceInitializer || !method.IsSpecialName) {
          if (!(method.DeclaringType is Interface) && !(method.DeclaringType is DelegateNode)) {
            if (this.IsLessAccessible(method.ReturnType, method)) {
              this.HandleError(method.Name, Error.ReturnTypeLessAccessibleThanMethod, this.GetTypeName(method.ReturnType), this.GetMethodSignature(method));
              this.HandleRelatedError(method.ReturnType);
            }
            this.CheckParameterTypeAccessibility(method.Parameters, method);
          }
        } else {
          if (method.Name != null && Checker.OperatorName[method.Name.UniqueIdKey] != null) {
            if (this.IsLessAccessible(method.ReturnType, method)) {
              this.HandleError(method.Name, Error.ReturnTypeLessAccessibleThanOperator, this.GetTypeName(method.ReturnType), this.GetMethodSignature(method));
              this.HandleRelatedError(method.ReturnType);
            }
            this.CheckParameterTypeAccessibility(method.Parameters, method);
          }
        }
      }

      if (!method.IsSpecialName) {
        TypeNodeList implementedTypes = method.ImplementedTypes;
        if (implementedTypes != null) {
          InterfaceList declaringTypeInterfaces = this.GetTypeView(method.DeclaringType).Interfaces;
          for (int i = 0, n = implementedTypes.Count; i < n; i++) {
            Interface iface = implementedTypes[i] as Interface;
            if (iface == null) continue;
            if (!this.IsAllowedAsImplementedType(declaringTypeInterfaces, iface)) {
              Node offendingNode = method.ImplementedTypeExpressions[i];
              this.HandleError(offendingNode, Error.ContainingTypeDoesNotImplement, this.GetMethodSignature(method), this.GetTypeName(iface));
              this.HandleRelatedError(iface);
              implementedTypes = null;
              break;
            }
          }
        }
        MethodList implementedMethods = method.ImplementedInterfaceMethods;
        for (int i = 0, n = implementedTypes == null ? 0 : implementedTypes.Count; i < n; i++) {
          Interface iface = implementedTypes[i] as Interface;
          if (iface == null) continue;
          Method m = implementedMethods == null ? null : implementedMethods[i];
          if (m == null) {
            this.HandleError(method.Name, Error.InterfaceMemberNotFound, this.GetMemberSignature(method), this.GetTypeName(iface));
            this.HandleRelatedError(iface);
          } else if (m.IsSpecialName)
            this.HandleError(method.Name, Error.CannotExplicitlyImplementAccessor, this.GetMethodSignature(method), this.GetMethodSignature(m));
        }
      }
      if ((method.Flags & MethodFlags.PInvokeImpl) != 0) {
        Error e = Error.None;
        if (this.shadowedAssembly != null) {
          // Make sure this method has a counterpart in the shadowed method
          TypeNode type = this.GetCorrespondingShadowedTypeNode(method.DeclaringType);
          if (type == null) {
            this.HandleError(method.DeclaringType, Error.TypeMissingInShadowedAssembly, this.GetTypeName(method.DeclaringType));
          } else {
            int numParams = method.Parameters == null ? 0 : method.Parameters.Count;
            TypeNode[] types = new TypeNode[numParams];
            for (int i = 0; i < numParams; i++) { types[i] = this.GetCorrespondingShadowedTypeNode(TypeNode.StripModifiers(method.Parameters[i].Type)); }
            if (this.GetTypeView(type).GetMethod(method.Name, types) == null) {
              this.HandleError(method, Error.MethodMissingInShadowedAssembly, this.GetMethodSignature(method));
            }
          }
        } else if (this.isCompilingAContractAssembly)
          e = Error.None;
        else if (method.Body != null)
          e = Error.PInvokeHasBody;
        else if (method.IsAbstract)
          e = Error.AbstractAndExtern;
        else if (method.PInvokeImportName == null || method.PInvokeModule == null) {
          if (method.Attributes == null || method.Attributes.Count == 0)
            e = Error.PInvokeWithoutModuleOrImportName;
          else
            method.Flags &= ~MethodFlags.PInvokeImpl;
        }
        if (e != Error.None)
          this.HandleError(method.Name, e, this.GetMethodSignature(method));
      }
      if (method.IsPropertySetter && (method.IsPure || method.IsConfined || method.IsStateIndependent)) {
        this.HandleError(method, Error.MemberCannotBeAnnotatedAsPure, this.GetMethodSignature(method));
      }
      this.currentFinallyClause = savedCurrentFinallyClause;
      this.currentMethod = savedCurrentMethod;
      this.returnNode = savedReturnNode;
      this.yieldNode = savedYieldNode;
      return result;
    }
Пример #44
0
 public virtual TypeNodeList VisitTypeReferenceList(TypeNodeList typeReferences)
 {
     if (typeReferences == null) return null;
     for (int i = 0, n = typeReferences.Count; i < n; i++)
         typeReferences[i] = this.VisitTypeReference(typeReferences[i]);
     return typeReferences;
 }
Пример #45
0
        private static TypeNodeList DuplicateTypeParameterList(TypeNodeList typeParameters, int offsetIndex, TypeNode declaringType)
        {
            if (typeParameters == null) return null;

            Duplicator dup = new Duplicator(declaringType.DeclaringModule, null);
            dup.FindTypesToBeDuplicated(typeParameters);
            
            TypeNodeList result = dup.VisitTypeParameterList(typeParameters);
            
            for (int i = 0; i < result.Count; i++)
            {
                TypeNode tn = result[i];
                
                tn.DeclaringType = declaringType;
                tn.DeclaringModule = declaringType.DeclaringModule;

                ITypeParameter tp = (ITypeParameter) tn;
                
                tp.ParameterListIndex = offsetIndex + i;
                tp.DeclaringMember = declaringType;
            }

            return result;
        }
Пример #46
0
 public MyMethodBodySpecializer(Module module, TypeNodeList source, TypeNodeList target)
     : base(module, source, target)
 {
 }
Пример #47
0
 public override void LookupAnonymousTypes(Identifier ns, TypeNodeList atypes){
   // 21 June 2005 -- For now, remove functionality of finding anonyous members: too slow,
   // and not needed for now since we are not allowing general quantifiers in contracts
   // But keep commented code in case we want to go back to it.
   return;
   //SpecSharpCompilerOptions coptions = this.currentOptions as SpecSharpCompilerOptions;
   //if (coptions != null && coptions.Compatibility) return;
   //base.LookupAnonymousTypes(ns, atypes);
 }
Пример #48
0
        private static MapClosureExpressionToOriginalExpression BuildMappingFromClosureToOriginal(TypeNode ClosureClass,
            Method MoveNextMethod, Method OriginalMethod)
        {
            Contract.Ensures(Contract.Result<MapClosureExpressionToOriginalExpression>() != null);

            Dictionary<string, Parameter> closureFieldsMapping = GetClosureFieldsMapping(ClosureClass, OriginalMethod);

            TypeNodeList TPListSource = ClosureClass.ConsolidatedTemplateParameters;

            if (TPListSource == null) TPListSource = new TypeNodeList();

            TypeNodeList TPListTarget = new TypeNodeList();

            if (OriginalMethod.DeclaringType != null &&
                OriginalMethod.DeclaringType.ConsolidatedTemplateParameters != null)
            {
                foreach (TypeNode tn in OriginalMethod.DeclaringType.ConsolidatedTemplateParameters)
                    TPListTarget.Add(tn);
            }

            if (OriginalMethod.TemplateParameters != null)
            {
                foreach (TypeNode tn in OriginalMethod.TemplateParameters)
                {
                    TPListTarget.Add(tn);
                }
            }

            Debug.Assert((TPListSource == null && TPListTarget == null) || TPListSource.Count == TPListTarget.Count);

            return new MapClosureExpressionToOriginalExpression(
                ClosureClass, closureFieldsMapping, TPListSource,
                TPListTarget, OriginalMethod);
        }
Пример #49
0
        /// <summary>
        /// This is used to build the catalog of types in the parsed assemblies
        /// </summary>
        /// <param name="types">The list of types from an assembly</param>
        private void StoreTypes(TypeNodeList types)
        {
            for(int i = 0; i < types.Count; i++)
            {
                this.StoreType(types[i]);

                if(this.Canceled)
                    break;
            }
        }
Пример #50
0
            public MapClosureExpressionToOriginalExpression(TypeNode Closure,
                Dictionary<string, Parameter> closureParametersMapping,
                TypeNodeList TPListSource, TypeNodeList TPListTarget, Method method)
            {
                this.closureParametersMapping = closureParametersMapping;

                if (TPListTarget == null || TPListSource == null || TPListSource.Count == 0 || TPListTarget.Count == 0)
                    specializer = null;
                else
                    specializer = new MyMethodBodySpecializer(Closure.DeclaringModule, TPListSource, TPListTarget);

                this.method = method;
                this.closureUnspec = HelperMethods.Unspecialize(Closure);
            }
Пример #51
0
        private void RecordExtensionMethods(XmlWriter writer, Object info)
        {
            NamespaceList spaces = (NamespaceList)info;

            foreach (Namespace space in spaces)
            {
                TypeNodeList types = space.Types;
                foreach (TypeNode type in types)
                {
                    MemberList members = type.Members;

                    // go through the members, looking for fields signaling extension methods
                    foreach (Member member in members)
                    {
                        Method method = member as Method;
                        if (method == null)
                        {
                            continue;
                        }

                        if (!reflector.ApiFilter.IsExposedMember(method))
                        {
                            continue;
                        }

                        if (!HasExtensionAttribute(method))
                        {
                            continue;
                        }

                        ParameterList parameters   = method.Parameters;
                        TypeNode      extendedType = parameters[0].Type;

                        // recognize generic extension methods where the extended type is a specialization of a generic type,
                        // and the extended type's specialized template arg is a type parameter declared by the generic extension method
                        // In this case, we need to save a TypeNode for the non-specialized type in the index,
                        // because a TypeNode for the specialized type won't match correctly in AddExtensionMethods
                        // Note: we are not interested in extended types that are specialized by a specific type rather than by the extension method's template param.
                        if (method.IsGeneric && (method.TemplateParameters.Count > 0))
                        {
                            if (extendedType.IsGeneric && (extendedType.TemplateArguments != null) && (extendedType.TemplateArguments.Count == 1))
                            {
                                // is the extended type's template arg a template parameter, rather than a specialized type?
                                TypeNode arg = extendedType.TemplateArguments[0];
                                if (arg.IsTemplateParameter)
                                {
                                    // is the template parameter declared on the extension method
                                    ITypeParameter gtp = (ITypeParameter)arg;
                                    if ((gtp.DeclaringMember == method) && (gtp.ParameterListIndex == 0))
                                    {
                                        // get a TypeNode for the non-specialized type
                                        extendedType = ReflectionUtilities.GetTemplateType(extendedType);
                                    }
                                }
                            }
                        }

                        List <Method> methods = null;
                        if (!index.TryGetValue(extendedType, out methods))
                        {
                            methods = new List <Method>();
                            index.Add(extendedType, methods);
                        }
                        methods.Add(method);
                    }
                }
            }
        }
Пример #52
0
        /// <summary>
        /// Write out a method name
        /// </summary>
        /// <param name="method">The method for which to write out the name</param>
        /// <param name="sb">The string builder to which the name is written</param>
        private static void WriteMethod(Method method, StringBuilder sb)
        {
            string name = method.Name.Name;

            WriteType(method.DeclaringType, sb);

            Method eiiMethod = null;

            if (method.IsPrivate && method.IsVirtual)
            {
                eiiMethod = method.ImplementedInterfaceMethods.FirstOrDefault();
            }

            if (eiiMethod != null)
            {
                TypeNode eiiType = eiiMethod.DeclaringType;

                if (eiiType != null)
                {
                    if (eiiType.Template != null)
                    {
                        sb.Append(".");
                        WriteTemplate(eiiType, sb);
                    }
                    else
                    {
                        StringBuilder eiiName = new StringBuilder();

                        WriteType(eiiType, eiiName);
                        sb.Append(".");
                        sb.Append(eiiName.ToString().Replace('.', '#'));
                    }
                }

                sb.Append("#");
                sb.Append(eiiMethod.Name.Name);
            }
            else
            {
                sb.Append('.');
                sb.Append(name);
            }

            if (method.IsGeneric)
            {
                TypeNodeList genericParameters = method.TemplateParameters;

                if (genericParameters != null)
                {
                    sb.Append("``");
                    sb.Append(genericParameters.Count);
                }
            }

            WriteParameters(method.Parameters, sb);

            // Add ~ for conversion operators
            if (name == "op_Implicit" || name == "op_Explicit")
            {
                sb.Append("~");
                WriteType(method.ReturnType, sb);
            }
        }
Пример #53
0
        //=====================================================================

        /// <summary>
        /// This finds all attached properties and events, adds information about them to the types, and tracks
        /// them for adding to the reflection data later in the other callbacks.
        /// </summary>
        /// <param name="writer">The reflection data XML writer</param>
        /// <param name="info">For this callback, the information object is a namespace list</param>
        private void AddAttachedMembers(XmlWriter writer, object info)
        {
            NamespaceList spaces = (NamespaceList)info;

            foreach (Namespace space in spaces)
            {
                TypeNodeList types = space.Types;

                foreach (TypeNode type in types)
                {
                    MemberList members = new MemberList(type.Members);

                    // Go through the members looking for fields signaling attached properties
                    foreach (Member member in members)
                    {
                        // We need a visible, static, field...
                        if (!member.IsStatic || !member.IsVisibleOutsideAssembly || member.NodeType != NodeType.Field)
                        {
                            continue;
                        }

                        Field field = (Field)member;

                        // ... of type dependency property ...
                        if (field.Type.FullName != dependencyPropertyTypeName)
                        {
                            continue;
                        }

                        // ... with a name ending in "Property".
                        string name = field.Name.Name;

                        if (!name.EndsWith(dependencyPropertySuffix, StringComparison.Ordinal))
                        {
                            continue;
                        }

                        name = name.Substring(0, name.Length - dependencyPropertySuffix.Length);

                        // Look for a getter and/or a setter
                        Method getter = null;

                        MemberList candidateGetters = type.GetMembersNamed(new Identifier("Get" + name));

                        foreach (var candidateGetter in candidateGetters)
                        {
                            if (candidateGetter.NodeType == NodeType.Method && candidateGetter.IsStatic &&
                                candidateGetter.IsVisibleOutsideAssembly)
                            {
                                getter = (Method)candidateGetter;
                            }
                        }

                        Method setter = null;

                        MemberList candidateSetters = type.GetMembersNamed(new Identifier("Set" + name));

                        foreach (var candidateSetter in candidateSetters)
                        {
                            if (candidateSetter.NodeType == NodeType.Method && candidateSetter.IsStatic &&
                                candidateSetter.IsVisibleOutsideAssembly)
                            {
                                setter = (Method)candidateSetter;
                            }
                        }

                        if (getter == null && setter == null)
                        {
                            continue;
                        }

                        // Make sure there isn't already such a property
                        Property existingProperty = type.GetProperty(new Identifier(name), new TypeNode[0]);

                        if (existingProperty != null && existingProperty.IsVisibleOutsideAssembly)
                        {
                            continue;
                        }

                        // Okay, this really is an indication of an attached property, so create one
                        Property attachedProperty = new Property(type, null, PropertyFlags.None, new Identifier(name), getter, setter);

                        // Attached properties have no parameters
                        attachedProperty.Parameters = ParameterList.Empty;

                        // Attached properties are instance properties
                        type.Members.Add(attachedProperty);

                        attachedMembers.Add(attachedProperty, field);
                    }

                    // Go through the members, looking for fields signaling attached events
                    foreach (Member member in members)
                    {
                        // Follow a similar approach as above but for an event
                        if (!member.IsStatic || !member.IsVisibleOutsideAssembly)
                        {
                            continue;
                        }

                        if (member.NodeType != NodeType.Field)
                        {
                            continue;
                        }

                        Field field = (Field)member;

                        if (field.Type.FullName != routedEventTypeName)
                        {
                            continue;
                        }

                        string name = field.Name.Name;

                        if (!name.EndsWith(routedEventSuffix, StringComparison.Ordinal))
                        {
                            continue;
                        }

                        name = name.Substring(0, name.Length - routedEventSuffix.Length);

                        Method adder = null;

                        MemberList candidateAdders = type.GetMembersNamed(new Identifier("Add" + name + "Handler"));

                        foreach (var candidateAdder in candidateAdders)
                        {
                            if (candidateAdder.NodeType == NodeType.Method && candidateAdder.IsStatic)
                            {
                                adder = (Method)candidateAdder;
                            }
                        }

                        Method remover = null;

                        MemberList candidateRemovers = type.GetMembersNamed(new Identifier("Remove" + name + "Handler"));

                        foreach (var candidateRemover in candidateRemovers)
                        {
                            if (candidateRemover.NodeType == NodeType.Method && candidateRemover.IsStatic)
                            {
                                remover = (Method)candidateRemover;
                            }
                        }

                        if (adder == null || remover == null)
                        {
                            continue;
                        }

                        // Make sure there isn't already such an event
                        Event existingEvent = type.GetEvent(new Identifier(name));

                        if (existingEvent != null && existingEvent.IsVisibleOutsideAssembly)
                        {
                            continue;
                        }

                        // Okay, this really is an indication of an attached event, so create one
                        TypeNode handler = adder.Parameters[1].Type;

                        Event attachedEvent = new Event(type, null, EventFlags.None, new Identifier(name), adder, null, remover, handler);
                        attachedEvent.HandlerFlags = adder.Flags;

                        type.Members.Add(attachedEvent);

                        attachedMembers.Add(attachedEvent, field);
                    }
                }
            }
        }
Пример #54
0
        //=====================================================================

        /// <summary>
        /// Write out a type name
        /// </summary>
        /// <param name="type">The type for which to write out the name</param>
        /// <param name="sb">The string builder to which the name is written</param>
        private static void WriteType(TypeNode type, StringBuilder sb)
        {
            switch (type.NodeType)
            {
            case NodeType.ArrayType:
                ArrayType array = (ArrayType)type;
                WriteType(array.ElementType, sb);

                sb.Append("[");

                if (array.Rank > 1)
                {
                    for (int i = 0; i < array.Rank; i++)
                    {
                        if (i > 0)
                        {
                            sb.Append(",");
                        }

                        sb.Append("0:");
                    }
                }

                sb.Append("]");
                break;

            case NodeType.Reference:
                Reference reference = (Reference)type;
                WriteType(reference.ElementType, sb);
                sb.Append("@");
                break;

            case NodeType.Pointer:
                Pointer pointer = (Pointer)type;
                WriteType(pointer.ElementType, sb);
                sb.Append("*");
                break;

            case NodeType.OptionalModifier:
                TypeModifier optionalModifierClause = (TypeModifier)type;
                WriteType(optionalModifierClause.ModifiedType, sb);
                sb.Append("!");
                WriteType(optionalModifierClause.Modifier, sb);
                break;

            case NodeType.RequiredModifier:
                TypeModifier requiredModifierClause = (TypeModifier)type;
                WriteType(requiredModifierClause.ModifiedType, sb);

                // !EFW - Skip writing out the modifier if it's an InAttribute.  Not sure if this is the best
                // way to handle this so we'll have to wait and see.
                if (requiredModifierClause.Modifier.Name.Name != "InAttribute")
                {
                    sb.Append("|");
                    WriteType(requiredModifierClause.Modifier, sb);
                }
                break;

            default:
                if (type.IsTemplateParameter)
                {
                    ITypeParameter gtp = (ITypeParameter)type;

                    if (gtp.DeclaringMember is TypeNode)
                    {
                        sb.Append("`");
                    }
                    else
                    if (gtp.DeclaringMember is Method)
                    {
                        sb.Append("``");
                    }
                    else
                    {
                        throw new InvalidOperationException("Generic parameter not on type or method");
                    }

                    sb.Append(gtp.ParameterListIndex);
                }
                else
                {
                    // Namespace
                    TypeNode declaringType = type.DeclaringType;

                    if (declaringType != null)
                    {
                        // Names of nested types begin with outer type name
                        WriteType(declaringType, sb);
                        sb.Append(".");
                    }
                    else
                    {
                        // Otherwise just prefix with the namespace
                        Identifier space = type.Namespace;

                        if (space != null && !String.IsNullOrEmpty(space.Name))
                        {
                            sb.Append(space.Name);
                            sb.Append(".");
                        }
                    }

                    // Name
                    sb.Append(type.GetUnmangledNameWithoutTypeParameters());

                    // Generic parameters
                    if (type.IsGeneric)
                    {
                        // Number of parameters
                        TypeNodeList parameters = type.TemplateParameters;

                        if (parameters != null)
                        {
                            sb.Append('`');
                            sb.Append(parameters.Count);
                        }

                        // Arguments
                        TypeNodeList arguments = type.TemplateArguments;

                        if (arguments != null && arguments.Count > 0)
                        {
                            sb.Append("{");

                            for (int i = 0; i < arguments.Count; i++)
                            {
                                if (i > 0)
                                {
                                    sb.Append(",");
                                }

                                WriteType(arguments[i], sb);
                            }

                            sb.Append("}");
                        }
                    }
                }
                break;
            }
        }
Пример #55
0
        public static TypeNode GetTemplateType(TypeNode type)
        {
            if (type == null)
            {
                throw new ArgumentNullException("type");
            }
            // Console.WriteLine(type.FullName);

            // only generic types have templates
            if (!type.IsGeneric)
            {
                return(type);
            }

            if (type.DeclaringType == null)
            {
                // if the type is not nested, life is simpler

                // if the type is not specified, the type is the template
                if (type.TemplateArguments == null)
                {
                    return(type);
                }

                // otherwise, construct the template type identifier and use it to fetch the template type
                Module     templateModule = type.DeclaringModule;
                Identifier name           = new Identifier(String.Format("{0}`{1}", type.GetUnmangledNameWithoutTypeParameters(), type.TemplateArguments.Count));
                Identifier space          = type.Namespace;
                TypeNode   template       = templateModule.GetType(space, name);
                return(template);
            }
            else
            {
                // if the type is nested, life is harder; we have to walk up the chain, constructing
                // un-specialized identifiers as we go, then walk back down the chain, fetching
                // template types as we go

                // create a stack to keep track of identifiers
                Stack <Identifier> identifiers = new Stack <Identifier>();

                // populate the stack with the identifiers of all the types up to the outermost type
                TypeNode current = type;
                while (true)
                {
                    int count = 0;
                    if ((current.TemplateArguments != null) && (current.TemplateArguments.Count > count))
                    {
                        count = current.TemplateArguments.Count;
                    }
                    if ((current.TemplateParameters != null) && (current.TemplateParameters.Count > count))
                    {
                        count = current.TemplateParameters.Count;
                    }
                    TypeNodeList arguments = current.TemplateParameters;
                    if (count == 0)
                    {
                        identifiers.Push(new Identifier(current.GetUnmangledNameWithoutTypeParameters()));
                    }
                    else
                    {
                        identifiers.Push(new Identifier(String.Format("{0}`{1}", current.GetUnmangledNameWithoutTypeParameters(), count)));
                    }
                    // Console.WriteLine("U {0} {1}", identifiers.Peek(), CountArguments(current));
                    if (current.DeclaringType == null)
                    {
                        break;
                    }
                    current = current.DeclaringType;
                }

                // fetch a TypeNode representing that outermost type
                Module     module = current.DeclaringModule;
                Identifier space  = current.Namespace;
                current = module.GetType(space, identifiers.Pop());

                // move down the stack to the inner type we want
                while (identifiers.Count > 0)
                {
                    current = (TypeNode)current.GetMembersNamed(identifiers.Pop())[0];
                    // Console.WriteLine("D {0} {1}", current.GetFullUnmangledNameWithTypeParameters(), CountArguments(current));
                }

                // whew, finally we've got it
                return(current);
            }
        }
Пример #56
0
        private static void DuplicateMember(DuplicatorForContractsAndClosures dup, FindClosurePartsToDuplicate fmd,
            int memindex, TypeNode targetType)
        {
            Member mem = fmd.MembersToDuplicate[memindex];
            
            TypeNode nestedType = mem as TypeNode;
            Method closureInstanceMethod = mem as Method;
            Method closureMethodTemplate = closureInstanceMethod;
            
            while (closureMethodTemplate != null && closureMethodTemplate.Template != null)
            {
                closureMethodTemplate = closureMethodTemplate.Template;
            }

            if (nestedType != null)
            {
                // if nested type is nested inside another type to be duplicated, skip it
                if (nestedType.DeclaringType != null && fmd.MembersToDuplicate.Contains(nestedType.DeclaringType))
                    return;
                
                // For call-site wrappers, we end up having multiple methods from the same original contract method
                // thus we have to avoid duplicating the same closure type multiple times.
                var duplicatedNestedType = FindExistingClosureType(targetType, nestedType);
                if (duplicatedNestedType == null)
                {
                    dup.FindTypesToBeDuplicated(new TypeNodeList(nestedType));

                    // if parent type is generic and different from the target type, then we may have to include all the
                    // consolidated type parameters excluding the ones from the target type.
                    TypeNodeList originalTemplateParameters = FindNonStandardTypeParametersToBeDuplicated(fmd,
                        nestedType, targetType);

                    duplicatedNestedType = dup.Visit(mem) as TypeNode;
                    if (originalTemplateParameters != null)
                    {
                        int parentParameters = (targetType.ConsolidatedTemplateParameters == null)
                            ? 0
                            : targetType.ConsolidatedTemplateParameters.Count;

                        if (parentParameters > 0 &&
                            (nestedType.DeclaringType.ConsolidatedTemplateParameters == null ||
                             nestedType.DeclaringType.ConsolidatedTemplateParameters.Count == 0))
                        {
                            // type is turning from non-generic to generic
                            Debug.Assert(false);
                        }

                        TypeNodeList dupTPs = DuplicateTypeParameterList(originalTemplateParameters, parentParameters, duplicatedNestedType);

                        duplicatedNestedType.TemplateParameters = dupTPs;
                        dup.SafeAddMember(targetType, duplicatedNestedType, mem);


                        // populate the self specialization forwarding
                        //  OriginalDecl<X,Y,Z>.NestedType<A,B,C> -> WrapperType<U,V,W>.NewNestedType<X,Y,Z,A,B,C>
                        //var oldSelfInstanceType = nestedType.GetGenericTemplateInstance(targetModule, nestedType.ConsolidatedTemplateParameters);
                        //var newSelfInstanceType = duplicatedNestedType.GetGenericTemplateInstance(targetModule, duplicatedNestedType.ConsolidatedTemplateParameters);
                        //dup.DuplicateFor[oldSelfInstanceType.UniqueKey] = newSelfInstanceType;
                        // specialize duplicated type
                        var specializer = new Specializer(targetType.DeclaringModule, originalTemplateParameters, dupTPs);
                        
                        specializer.VisitTypeParameterList(dupTPs); // for constraints etc.
                        specializer.VisitTypeNode(duplicatedNestedType);

                        var bodySpecializer = new MethodBodySpecializer(targetType.DeclaringModule,
                            originalTemplateParameters, dupTPs);

                        bodySpecializer.Visit(duplicatedNestedType);
                        
                        // after copying the closure class, clear the self specialization forwarding
                        //  OriginalDecl<X,Y,Z>.NestedType<A,B,C> -> WrapperType<U,V,W>.NewNestedType<X,Y,Z,A,B,C>
                        //dup.DuplicateFor[oldSelfInstanceType.UniqueKey] = null;
                    }
                    else
                    {
                        dup.SafeAddMember(targetType, duplicatedNestedType, mem);
                    }
                }
                else
                {
                    // already copied type previously
                    dup.DuplicateFor[nestedType.UniqueKey] = duplicatedNestedType;
#if false
        if (nestedType.ConsolidatedTemplateArguments != null)
        {
            // populate the self specialization forwarding
            //  NestedType<Self1,Self2> -> NewNestedType<NewSelf1,NewSelf2>
            var origSelfInstantiation = nestedType.DeclaringType.GetTemplateInstance(nestedType, nestedType.DeclaringType.TemplateParameters).GetNestedType(nestedType.Name);
            var newSelfInstantiation = duplicatedNestedType.GetGenericTemplateInstance(targetModule, duplicatedNestedType.ConsolidatedTemplateParameters);
            dup.DuplicateFor[origSelfInstantiation.UniqueKey] = newSelfInstantiation;
            // Also forward ContractType<A,B>.NestedType instantiated at target ContractType<X,Y>.NestedType to
            // TargetType<X,Y,Z>.NewNestedType<X,Y>, since this reference may appear in the contract itself.
            var consolidatedContractTemplateArguments = sourceMethod.DeclaringType.ConsolidatedTemplateArguments;
            var instantiatedNestedOriginal = nestedType.DeclaringType.GetGenericTemplateInstance(targetModule, consolidatedContractTemplateArguments).GetNestedType(nestedType.Name);
            dup.DuplicateFor[instantiatedNestedOriginal.UniqueKey] = duplicatedNestedType.GetTemplateInstance(targetType, consolidatedContractTemplateArguments);
        }
        else
        {
            Debugger.Break();
        }
#endif
                }
            }
            else if (closureInstanceMethod != null && closureMethodTemplate != null &&
                     !fmd.MembersToDuplicate.Contains(closureMethodTemplate.DeclaringType))
            {
                Method closureMethod = closureMethodTemplate;

                Debug.Assert(closureMethod.Template == null);
                
                //var m = FindExistingClosureMethod(targetType, closureMethod);
                Method m = null;
                
                // why did we ever try to find an existing one? This can capture a completely unrelated closure that happens to match by name.
                if (m == null)
                {
                    Method dupMethod = dup.Visit(closureMethod) as Method;
                    TypeNodeList actuals;

                    TransformOriginalConsolidatedTypeFormalsIntoMethodFormals(dupMethod, closureMethod,
                        closureInstanceMethod, out actuals);

                    // now setup a forwarding from the closureInstanceMethod to the new instance
                    Method newInstance = dupMethod.GetTemplateInstance(dupMethod.DeclaringType, actuals);
                    newInstance.Name = dupMethod.Name;

                    dup.DuplicateFor[closureInstanceMethod.UniqueKey] = newInstance;

                    dup.SafeAddMember(targetType, dupMethod, closureMethod);

                    // special case when resulting method is generic and instance, then we need to make "this" a parameter
                    // and the method static, otherwise, there's a type mismatch between the "this" and the explicitly generic parameter types used
                    // in arguments.
                    var originalParentTemplateParameters = closureMethod.DeclaringType.ConsolidatedTemplateParameters;
                    if (!dupMethod.IsStatic && originalParentTemplateParameters != null && originalParentTemplateParameters.Count > 0)
                    {
                        var oldThis = dupMethod.ThisParameter;
                        oldThis.Type = dup.PossiblyRemapContractClassToInterface(oldThis.Type);
                        
                        dupMethod.Flags |= MethodFlags.Static;
                        dupMethod.CallingConvention &= ~CallingConventionFlags.HasThis;
                        
                        var oldParameters = dupMethod.Parameters;
                        
                        dupMethod.Parameters = new ParameterList(oldParameters.Count + 1);
                        dupMethod.Parameters.Add(oldThis); // make explicit
                        
                        for (int i = 0; i < oldParameters.Count; i++)
                        {
                            dupMethod.Parameters.Add(oldParameters[i]);
                        }

                        // now need to specialize transforming original parameters into first n method template parameters
                        var targetTypeParameters = new TypeNodeList(originalParentTemplateParameters.Count);
                        for (int i = 0; i < originalParentTemplateParameters.Count; i++)
                        {
                            targetTypeParameters.Add(dupMethod.TemplateParameters[i]);
                        }

                        var specializer = new Specializer(targetType.DeclaringModule, originalParentTemplateParameters, targetTypeParameters);
                        specializer.VisitMethod(dupMethod);

                        var bodySpecializer = new MethodBodySpecializer(targetType.DeclaringModule,
                            originalParentTemplateParameters, targetTypeParameters);

                        bodySpecializer.VisitMethod(dupMethod);
                    }
                }
            }
            else if (closureInstanceMethod != null)
            {
                var m = FindExistingClosureMethod(targetType, closureInstanceMethod);
                if (m == null)
                {
                    Member duplicatedMember = dup.Visit(mem) as Member;
                    dup.SafeAddMember(targetType, duplicatedMember, mem);
                }
            }
            else
            {
                Member duplicatedMember = dup.Visit(mem) as Member;
                dup.SafeAddMember(targetType, duplicatedMember, mem);
            }
        }
Пример #57
0
        public override TypeNodeList VisitTypeNodeList(TypeNodeList types)
        {
            if (types == null) return null;
            for (int i = 0; i < types.Count; i++)
            {
                types[i] = (TypeNode)this.Visit(types[i]);

                if (this.options.BlankLinesBetweenMembers && (i + 1 < types.Count))
                    WriteLine(string.Empty);
            }
            return types;
        }
Пример #58
0
        /// <summary>
        /// If source type is insided target type, only grab the type parameters up to the target type. Otherwise, grab consolidated.
        /// </summary>
        private static TypeNodeList FindNonStandardTypeParametersToBeDuplicated(FindClosurePartsToDuplicate fmd, TypeNode sourceType, TypeNode targetType)
        {
            Debug.Assert(TypeNode.IsCompleteTemplate(sourceType));
            Debug.Assert(TypeNode.IsCompleteTemplate(targetType));

            TypeNodeList result = null;
            if (sourceType.DeclaringType != null)
            {
                if (fmd.MembersToDuplicate.Contains(sourceType.DeclaringType))
                {
                    Debug.Assert(false);
                    return null;
                }

                if (sourceType.DeclaringType == targetType) return null;

                if (IsInsideOf(sourceType, targetType))
                {
                    // difficult case. Grab consolidated type parameters, except the ones up from the target type
                    var sourceConsolidated = sourceType.ConsolidatedTemplateParameters;
                    if (sourceConsolidated == null || sourceConsolidated.Count == 0) return null;

                    var targetConsolidated = targetType.ConsolidatedTemplateParameters;
                    if (targetConsolidated == null || targetConsolidated.Count == 0) return sourceConsolidated;
                    
                    if (sourceConsolidated.Count == targetConsolidated.Count) return null; // no extra type parameters

                    result = new TypeNodeList(sourceConsolidated.Count - targetConsolidated.Count);
                    for (int i = 0; i < sourceConsolidated.Count; i++)
                    {
                        if (i < targetConsolidated.Count) continue;
                        result.Add(sourceConsolidated[i]);
                        
                        return result;
                    }
                }
                else
                {
                    // For Roslyn-based closures we need to combine all the types from source and target types together.
                    if (sourceType.IsRoslynBasedStaticClosure())
                    {
                        var sourceConsolidated = sourceType.ConsolidatedTemplateParameters;
                        if (sourceConsolidated == null || sourceConsolidated.Count == 0) return null;
                        
                        var targetConsolidated = targetType.ConsolidatedTemplateParameters;
                        
                        if (targetConsolidated == null || targetConsolidated.Count == 0) return sourceConsolidated;
                        
                        if (sourceConsolidated.Count == targetConsolidated.Count)
                            return null; // no extra type parameters

                        result = new TypeNodeList(sourceConsolidated.Count + targetConsolidated.Count);

                        for (int i = 0; i < targetConsolidated.Count; i++)
                        {
                            result.Add(targetConsolidated[i]);
                        }

                        for (int i = 0; i < sourceConsolidated.Count; i++)
                        {
                            result.Add(sourceConsolidated[i]);
                        }

                        return result;
                    }

                    result = sourceType.ConsolidatedTemplateParameters;
                }
            }

            return result;
        }
Пример #59
0
 public virtual bool ImplementedTypesOverlap(TypeNodeList types1, TypeNodeList types2) {
   if (types1 == types2) return true; //usually means they are both null
   if (types1 == null || types2 == null) return false;
   for (int i = 0, n = types1.Count; i < n; i++) {
     TypeNode t1 = types1[i];
     if (t1 == null) continue;
     for (int j = 0, m = types2.Count; j < m; j++) {
       TypeNode t2 = types2[j];
       if (t2 == null) continue;
       if (t1 == t2) return true;
     }
   }
   return false;
 }
Пример #60
0
    public override Statement VisitTry(Try Try) {
      if (Try == null) return null;
      bool savedInsideTryBlock = this.insideTryBlock;
      this.insideTryBlock = true;

      // when visiting the try block, use a newly computed set of allowed exceptions.
      // the set is whatever the current set is augmented with the set of exceptions listed in the
      // catch clauses
      TypeNodeList newAllowedExceptions = this.allowedExceptions.Clone();
      CatchList cl = Try.Catchers;
      if (cl != null) {
        for (int i = 0, n = cl.Count; i < n; i++) {
          Catch c = cl[i];
          if (c == null) continue;
          // BUGBUG? In both cases, should we just automatically add to the list or first see if
          // some exception already in the list is a supertype of the one that is currently added?
          if (c.Type == null)
            // then this was "catch { }" meaning catch everything, so all checked exceptions will be caught
            newAllowedExceptions.Add(SystemTypes.ICheckedException);
          else if (this.GetTypeView(c.Type).IsAssignableTo(SystemTypes.ICheckedException))
            newAllowedExceptions.Add(c.Type);
        }
      }
      TypeNodeList saveAllowedExceptions = this.allowedExceptions;
      this.allowedExceptions = newAllowedExceptions;

      /* can't call the base visitor because after visiting the try block, the allowedExceptions
       * need to be restored before visiting the catchers.
       * So this is a copy of the body of StandardVisitor.VisitTry. If that ever changes, this
       * will need to be changed too!
      Statement result = base.VisitTry(Try);
      */
      Try.TryBlock = this.VisitBlock(Try.TryBlock);

      /* restore the list of allowed exceptions */
      this.allowedExceptions = saveAllowedExceptions;

      Try.Catchers = this.VisitCatchList(Try.Catchers);
      Try.Filters = this.VisitFilterList(Try.Filters);
      Try.FaultHandlers = this.VisitFaultHandlerList(Try.FaultHandlers);
      Try.Finally = (Finally)this.VisitFinally(Try.Finally);

      this.insideTryBlock = savedInsideTryBlock;
      CatchList catchers = Try.Catchers;
      if (catchers != null) {
        for (int i = 0, n = catchers.Count; i < n; i++) {
          Catch c = catchers[i];
          if (c == null) continue;
          if (c.Type == null) continue;
          for (int j = 0; j < i; j++) {
            Catch c0 = catchers[j];
            if (c0 == null || c0.Type == null) continue;
            if (this.GetTypeView(c.Type).IsAssignableTo(c0.Type))
              this.HandleError(c.TypeExpression, Error.UnreachableCatch, this.GetTypeName(c0.Type));
          }
        }
      }
      return Try;
    }