Exemplo n.º 1
0
        /// <summary>
        /// Writes an interface member reference to the output.
        /// </summary>
        public void WriteInterfaceMemberToOutput(
            JavascriptFormatter output, Compiler.Extensibility.IAstEmitter astEmitter,
            JSFunctionExpression enclosingFunction,
            JSMethod jsMethod, JSExpression method,
            TypeReferenceContext referenceContext
            )
        {
            int index;

            CachedInterfaceMemberRecord record;

            GenericParameter[] rewrittenGenericParameters = null;
            if (LocalCachingEnabled && PreferLocalCacheForGenericInterfaceMethodSignatures)
            {
                record = new CachedInterfaceMemberRecord(jsMethod.Reference.DeclaringType, jsMethod.Identifier);
            }
            else
            {
                var rewritten = GenericTypesRewriter.Normalized(jsMethod.Reference.DeclaringType);
                record = new CachedInterfaceMemberRecord(rewritten.CacheRecord, jsMethod.Identifier,
                                                         rewritten.RewritedGenericParameters.Length);
                rewrittenGenericParameters = rewritten.RewritedGenericParameters;
            }

            if (enclosingFunction.Method != null && enclosingFunction.Method.Method != null)
            {
                var      functionIdentifier = enclosingFunction.Method.Method.Identifier;
                CacheSet localSignatureSet;

                if (LocalCachedSets.TryGetValue(functionIdentifier, out localSignatureSet))
                {
                    if (localSignatureSet.InterfaceMembers.TryGetValue(record, out index))
                    {
                        output.WriteRaw("$im{0:X2}", index);

                        return;
                    }
                }
            }

            if (!Global.InterfaceMembers.TryGetValue(record, out index))
            {
                output.Identifier(jsMethod.Reference.DeclaringType, referenceContext, false);
                output.Dot();
                astEmitter.Emit(method);
            }
            else
            {
                output.WriteRaw("$IM{0:X2}", index);
                output.LPar();
                if (rewrittenGenericParameters != null)
                {
                    output.CommaSeparatedList(rewrittenGenericParameters, referenceContext);
                }
                output.RPar();
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// Writes a method signature to the output.
        /// </summary>
        public void WriteSignatureToOutput(
            JavascriptFormatter output, JSFunctionExpression enclosingFunction,
            MethodReference methodReference, MethodSignature methodSignature,
            TypeReferenceContext referenceContext,
            bool forConstructor
            )
        {
            int index;
            CachedSignatureRecord cacheRecord;

            GenericParameter[] rewrittenGenericParameters = null;
            if (LocalCachingEnabled && PreferLocalCacheForGenericMethodSignatures)
            {
                cacheRecord = new CachedSignatureRecord(methodReference,
                                                        GenericTypesRewriter.NormalizedConstructorSignature(methodReference, methodSignature, forConstructor),
                                                        forConstructor);
            }
            else
            {
                RewritedCacheRecord <MethodSignature> rewritten = GenericTypesRewriter.Normalized(methodReference,
                                                                                                  methodSignature, forConstructor);
                cacheRecord = new CachedSignatureRecord(methodReference, rewritten.CacheRecord, forConstructor,
                                                        rewritten.RewritedGenericParameters.Length);
                rewrittenGenericParameters = rewritten.RewritedGenericParameters;
            }

            if ((enclosingFunction.Method != null) && (enclosingFunction.Method.Method != null))
            {
                var      functionIdentifier = enclosingFunction.Method.Method.Identifier;
                CacheSet localSignatureSet;

                if (LocalCachedSets.TryGetValue(functionIdentifier, out localSignatureSet))
                {
                    if (localSignatureSet.Signatures.TryGetValue(cacheRecord, out index))
                    {
                        output.WriteRaw("$s{0:X2}", index);

                        return;
                    }
                }
            }

            if (!Global.Signatures.TryGetValue(cacheRecord, out index))
            {
                output.Signature(methodReference, methodSignature, referenceContext, forConstructor, true);
            }
            else
            {
                output.WriteRaw("$S{0:X2}", index);
                output.LPar();
                if (rewrittenGenericParameters != null)
                {
                    output.CommaSeparatedList(rewrittenGenericParameters, referenceContext);
                }
                output.RPar();
            }
        }
Exemplo n.º 3
0
            public static RewritedCacheRecord <TypeReference> Normalized(TypeReference declaringType)
            {
                var targetMappings = new Dictionary <GenericParameter, int>(new GenericParameterComparer());
                var resolvedType   = GenericTypesRewriter.ResolveTypeReference(
                    declaringType,
                    (tr, resolutionStack) => {
                    if (tr is GenericParameter)
                    {
                        var gp = (GenericParameter)tr;
                        return(GenericTypesRewriter.ReplaceWithGenericArgument(gp, targetMappings));
                    }
                    return(tr);
                },
                    null);

                var mappings = targetMappings.OrderBy(item => item.Value).Select(item => item.Key).ToArray();

                return(new RewritedCacheRecord <TypeReference>(resolvedType, mappings));
            }
Exemplo n.º 4
0
            private static TypeReference ResolveTypeReference(MethodReference method, TypeReference typeReference, Dictionary <GenericParameter, int> mappings)
            {
                var resolvedMethod = method.Resolve();

                return(GenericTypesRewriter.ResolveTypeReference(
                           typeReference,
                           (tr, resolutionStack) => {
                    if (tr is GenericParameter)
                    {
                        var gp = (GenericParameter)tr;

                        if (resolutionStack.Count(typeInStack => TypeUtil.TypesAreEqual(typeInStack, gp)) > 1)
                        {
                            return GenericTypesRewriter.ReplaceWithGenericArgument(gp, mappings);
                        }

                        var result = MethodSignature.ResolveGenericParameter(gp, method.DeclaringType);

                        if (result is GenericParameter)
                        {
                            gp = (GenericParameter)result;
                            result = null;
                        }
                        if (result == null)
                        {
                            if (gp.Owner is MethodReference)
                            {
                                var mr = (MethodReference)gp.Owner;
                                if (mr.Resolve() == resolvedMethod)
                                {
                                    return gp;
                                }
                            }

                            return GenericTypesRewriter.ReplaceWithGenericArgument(gp, mappings);
                        }

                        return result;
                    }
                    return tr;
                }, null));
            }
Exemplo n.º 5
0
        private void CacheInterfaceMember(TypeReference declaringType, string memberName)
        {
            var cacheLocally = false;
            var originalType = declaringType;

            var unexpandedType = declaringType;

            if (!TypeUtil.ExpandPositionalGenericParameters(unexpandedType, out declaringType))
            {
                declaringType = unexpandedType;
            }

            CachedInterfaceMemberRecord record;

            if (LocalCachingEnabled && PreferLocalCacheForGenericInterfaceMethodSignatures)
            {
                if (TypeUtil.IsOpenType(declaringType))
                {
                    cacheLocally = true;
                }
                record = new CachedInterfaceMemberRecord(declaringType, memberName);
            }
            else
            {
                var rewritten = GenericTypesRewriter.Normalized(declaringType);
                record = new CachedInterfaceMemberRecord(rewritten.CacheRecord, memberName,
                                                         rewritten.RewritedGenericParameters.Length);
            }

            var set = GetCacheSet(cacheLocally);

            if (!set.InterfaceMembers.ContainsKey(record))
            {
                set.InterfaceMembers.Add(record, set.InterfaceMembers.Count);
            }
        }
Exemplo n.º 6
0
        private void CacheSignature(MethodReference method, MethodSignature signature, bool isConstructor)
        {
            bool cacheLocally;
            CachedSignatureRecord record;

            if (LocalCachingEnabled && PreferLocalCacheForGenericMethodSignatures)
            {
                record = new CachedSignatureRecord(method,
                                                   GenericTypesRewriter.NormalizedConstructorSignature(method, signature, isConstructor), isConstructor);
                signature = record.Signature;

                Func <GenericParameter, bool> filter =
                    (gp) => {
                    // If the generic parameter can be expanded given the type that declared the method, don't cache locally.
                    var resolved = MethodSignature.ResolveGenericParameter(gp, method.DeclaringType);
                    // Note that we have to ensure the resolved type is not generic either. A generic parameter can resolve to a
                    //  *different* generic parameter, and that is still correct - i.e. SomeMethod<A> calls SomeMethod<B>,
                    //  in that case resolving B will yield A.
                    if ((resolved != gp) && (resolved != null) && !TypeUtil.IsOpenType(resolved))
                    {
                        return(false);
                    }

                    var ownerMethod = gp.Owner as MethodReference;
                    if (ownerMethod == null)
                    {
                        return(true);
                    }

                    if (ownerMethod == method)
                    {
                        return(false);
                    }
                    // FIXME: Nulls?
                    else if (ownerMethod.Resolve() == method.Resolve())
                    {
                        return(false);
                    }
                    else
                    {
                        return(true);
                    }
                };

                cacheLocally = false;

                if (TypeUtil.IsOpenType(signature.ReturnType, filter))
                {
                    cacheLocally = true;
                }
                else if (signature.ParameterTypes.Any((gp) => TypeUtil.IsOpenType(gp, filter)))
                {
                    cacheLocally = true;
                }
                else if (isConstructor && TypeUtil.IsOpenType(method.DeclaringType, filter))
                {
                    cacheLocally = true;
                }
            }
            else
            {
                cacheLocally = false;
                var rewritenInfo = GenericTypesRewriter.Normalized(method, signature, isConstructor);
                record = new CachedSignatureRecord(
                    method,
                    rewritenInfo.CacheRecord,
                    isConstructor,
                    rewritenInfo.RewritedGenericParameters.Length);
            }

            var set = GetCacheSet(cacheLocally);

            if (!set.Signatures.ContainsKey(record))
            {
                set.Signatures.Add(record, set.Signatures.Count);
            }
        }