private JsExpression CompileImportedTypeCheckCode(IType type, ref JsExpression @this, IRuntimeContext context, bool isTypeIs)
        {
            var def = type.GetDefinition();

            if (def == null)
            {
                return(null);
            }
            var ia = AttributeReader.ReadAttribute <ImportedAttribute>(def);

            if (ia == null || string.IsNullOrEmpty(ia.TypeCheckCode))
            {
                return(null);
            }

            // Can ignore errors here because they are caught by the metadata importer
            var method    = MetadataUtils.CreateTypeCheckMethod(type, _compilation);
            var tokens    = InlineCodeMethodCompiler.Tokenize(method, ia.TypeCheckCode, _ => {});
            int thisCount = tokens.Count(t => t.Type == InlineCodeToken.TokenType.This);

            if (!isTypeIs || thisCount > 0)
            {
                @this = context.EnsureCanBeEvaluatedMultipleTimes(@this, new JsExpression[0]);
            }
            return(JsExpression.LogicalAnd(
                       ReferenceNotEquals(@this, JsExpression.Null, context),
                       InlineCodeMethodCompiler.CompileExpressionInlineCodeMethodInvocation(method, tokens, @this, EmptyList <JsExpression> .Instance, n => { var t = ReflectionHelper.ParseReflectionName(n).Resolve(_compilation); return t.Kind == TypeKind.Unknown ? JsExpression.Null : InstantiateType(t, context); }, t => InstantiateTypeForUseAsTypeArgumentInInlineCode(t, context), _ => {})));
        }
예제 #2
0
        public static bool?ShouldGenericArgumentsBeIncluded(IMethod method)
        {
            var iga = AttributeReader.ReadAttribute <IncludeGenericArgumentsAttribute>(method);

            if (iga != null)
            {
                return(iga.Include);
            }
            var imp = AttributeReader.ReadAttribute <ImportedAttribute>(method.DeclaringTypeDefinition);

            if (imp != null)
            {
                return(false);
            }
            var def = AttributeReader.ReadAttribute <IncludeGenericArgumentsDefaultAttribute>(method.ParentAssembly.AssemblyAttributes);

            switch (def != null ? def.MethodDefault : GenericArgumentsDefault.IncludeExceptImported)
            {
            case GenericArgumentsDefault.IncludeExceptImported:
                return(true);

            case GenericArgumentsDefault.Ignore:
                return(false);

            case GenericArgumentsDefault.RequireExplicitSpecification:
                return(null);

            default:
                throw new ArgumentException("Invalid generic arguments default " + def.TypeDefault);
            }
        }
        public static bool IsReflectable(IMember member, IMetadataImporter metadataImporter)
        {
            var ra = AttributeReader.ReadAttribute <ReflectableAttribute>(member);

            if (ra != null)
            {
                return(ra.Reflectable);
            }
            if (member.Attributes.Any(a => metadataImporter.GetTypeSemantics(a.AttributeType.GetDefinition()).Type == TypeScriptSemantics.ImplType.NormalType))
            {
                return(true);                   // Any scriptable attribute will cause reflectability (unless [Reflectable(false)] was specified.
            }
            if (member.DeclaringType.Kind != TypeKind.Anonymous)
            {
                var tdr = AttributeReader.ReadAttribute <DefaultMemberReflectabilityAttribute>(member.DeclaringTypeDefinition);
                if (tdr != null)
                {
                    return(IsMemberReflectable(member, tdr.DefaultReflectability));
                }

                var adr = AttributeReader.ReadAttribute <DefaultMemberReflectabilityAttribute>(member.ParentAssembly.AssemblyAttributes);
                if (adr != null)
                {
                    return(IsMemberReflectable(member, adr.DefaultReflectability));
                }
            }

            return(false);
        }
예제 #4
0
 public static string GetModuleName(ITypeDefinition type)
 {
     for (var current = type; current != null; current = current.DeclaringTypeDefinition)
     {
         var mna = AttributeReader.ReadAttribute <ModuleNameAttribute>(type);
         if (mna != null)
         {
             return(!String.IsNullOrEmpty(mna.ModuleName) ? mna.ModuleName : null);
         }
     }
     return(GetModuleName(type.ParentAssembly));
 }
예제 #5
0
        private JsType ConvertType(JsClass type)
        {
            if (type.InstanceMethods.Any(m => m.Name == "runTests"))
            {
                _errorReporter.Region = type.CSharpTypeDefinition.Region;
                _errorReporter.Message(MessageSeverity.Error, 7019, string.Format("The type {0} cannot define a method named 'runTests' because it has a [TestFixtureAttribute].", type.CSharpTypeDefinition.FullName));
                return(type);
            }

            var instanceMethods = new List <JsMethod>();
            var tests           = new List <Tuple <string, string, bool, int?, JsFunctionDefinitionExpression> >();

            foreach (var method in type.InstanceMethods)
            {
                var testAttr = AttributeReader.ReadAttribute <TestAttribute>(method.CSharpMember);
                if (testAttr != null)
                {
                    if (!method.CSharpMember.IsPublic || !method.CSharpMember.ReturnType.IsKnownType(KnownTypeCode.Void) || ((IMethod)method.CSharpMember).Parameters.Count > 0 || ((IMethod)method.CSharpMember).TypeParameters.Count > 0)
                    {
                        _errorReporter.Region = method.CSharpMember.Region;
                        _errorReporter.Message(MessageSeverity.Error, 7020, string.Format("Method {0}: Methods decorated with a [TestAttribute] must be public, non-generic, parameterless instance methods that return void.", method.CSharpMember.FullName));
                    }

                    tests.Add(Tuple.Create(testAttr.Description ?? method.CSharpMember.Name, testAttr.Category, testAttr.IsAsync, testAttr.ExpectedAssertionCount >= 0 ? (int?)testAttr.ExpectedAssertionCount : null, method.Definition));
                }
                else
                {
                    instanceMethods.Add(method);
                }
            }

            var testInvocations = new List <JsExpression>();

            foreach (var category in tests.GroupBy(t => t.Item2).Select(g => new { Category = g.Key, Tests = g.Select(x => new { Description = x.Item1, IsAsync = x.Item3, ExpectedAssertionCount = x.Item4, Function = x.Item5 }) }).OrderBy(x => x.Category))
            {
                if (category.Category != null)
                {
                    testInvocations.Add(JsExpression.Invocation(JsExpression.Member(JsExpression.Identifier("QUnit"), "module"), JsExpression.String(category.Category)));
                }
                testInvocations.AddRange(category.Tests.Select(t => JsExpression.Invocation(JsExpression.Identifier(t.IsAsync ? "asyncTest" : "test"), t.ExpectedAssertionCount != null ? new JsExpression[] { JsExpression.String(t.Description), JsExpression.Number(t.ExpectedAssertionCount.Value), _runtimeLibrary.Bind(t.Function, JsExpression.This, this) } : new JsExpression[] { JsExpression.String(t.Description), _runtimeLibrary.Bind(t.Function, JsExpression.This, this) })));
            }

            instanceMethods.Add(new JsMethod(null, "runTests", null, JsExpression.FunctionDefinition(new string[0], new JsBlockStatement(testInvocations.Select(t => new JsExpressionStatement(t))))));

            var result = type.Clone();

            result.InstanceMethods.Clear();
            foreach (var m in instanceMethods)
            {
                result.InstanceMethods.Add(m);
            }
            return(result);
        }
예제 #6
0
 public IEnumerable <JsType> Rewrite(IEnumerable <JsType> types)
 {
     foreach (var type in types)
     {
         var cls = type as JsClass;
         if (cls != null)
         {
             var attr = AttributeReader.ReadAttribute <TestFixtureAttribute>(type.CSharpTypeDefinition);
             yield return(attr != null?ConvertType(cls) : type);
         }
         else
         {
             yield return(type);
         }
     }
 }
        private JsExpression GetMetadataDescriptor(ITypeDefinition type, bool isGenericSpecialization)
        {
            var properties           = new List <JsObjectLiteralProperty>();
            var scriptableAttributes = type.Attributes.Where(a => !a.IsConditionallyRemoved && _metadataImporter.GetTypeSemantics(a.AttributeType.GetDefinition()).Type == TypeScriptSemantics.ImplType.NormalType).ToList();

            if (scriptableAttributes.Count != 0)
            {
                properties.Add(new JsObjectLiteralProperty("attr", JsExpression.ArrayLiteral(scriptableAttributes.Select(a => MetadataUtils.ConstructAttribute(a, type, _compilation, _metadataImporter, _namer, _runtimeLibrary, _errorReporter)))));
            }
            if (type.Kind == TypeKind.Interface && MetadataUtils.IsJsGeneric(type, _metadataImporter) && type.TypeParameters != null && type.TypeParameters.Any(typeParameter => typeParameter.Variance != VarianceModifier.Invariant))
            {
                properties.Add(new JsObjectLiteralProperty("variance", JsExpression.ArrayLiteral(type.TypeParameters.Select(typeParameter => JsExpression.Number(ConvertVarianceToInt(typeParameter.Variance))))));
            }
            if (type.Kind == TypeKind.Class)
            {
                var members = type.Members.Where(m => MetadataUtils.IsReflectable(m, _metadataImporter))
                              .OrderBy(m => m, MemberOrderer.Instance)
                              .Select(m => {
                    _errorReporter.Region = m.Region;
                    return(MetadataUtils.ConstructMemberInfo(m, _compilation, _metadataImporter, _namer, _runtimeLibrary, _errorReporter, t => _runtimeLibrary.InstantiateType(t, isGenericSpecialization ? _genericSpecializationReflectionRuntimeContext : _defaultReflectionRuntimeContext), includeDeclaringType: false));
                })
                              .ToList();
                if (members.Count > 0)
                {
                    properties.Add(new JsObjectLiteralProperty("members", JsExpression.ArrayLiteral(members)));
                }

                var aua = AttributeReader.ReadAttribute <AttributeUsageAttribute>(type);
                if (aua != null)
                {
                    if (!aua.Inherited)
                    {
                        properties.Add(new JsObjectLiteralProperty("attrNoInherit", JsExpression.True));
                    }
                    if (aua.AllowMultiple)
                    {
                        properties.Add(new JsObjectLiteralProperty("attrAllowMultiple", JsExpression.True));
                    }
                }
            }
            if (type.Kind == TypeKind.Enum && AttributeReader.HasAttribute <FlagsAttribute>(type))
            {
                properties.Add(new JsObjectLiteralProperty("enumFlags", JsExpression.True));
            }

            return(properties.Count > 0 ? JsExpression.ObjectLiteral(properties) : null);
        }
예제 #8
0
        public static bool DoesTypeObeyTypeSystem(ITypeDefinition type)
        {
            var ia = AttributeReader.ReadAttribute <ImportedAttribute>(type);

            return(ia == null || ia.ObeysTypeSystem);
        }
예제 #9
0
        /// <summary>
        /// Determines the preferred name for a member. The first item is the name, the second item is true if the name was explicitly specified.
        /// </summary>
        public static Tuple <string, bool> DeterminePreferredMemberName(IMember member, bool minimizeNames)
        {
            member = UnwrapValueTypeConstructor(member);

            bool isConstructor        = member is IMethod && ((IMethod)member).IsConstructor;
            bool isAccessor           = member is IMethod && ((IMethod)member).IsAccessor;
            bool isPreserveMemberCase = IsPreserveMemberCase(member.DeclaringTypeDefinition);

            string defaultName;

            if (isConstructor)
            {
                defaultName = "$ctor";
            }
            else if (!CanBeMinimized(member))
            {
                defaultName = isPreserveMemberCase ? member.Name : MakeCamelCase(member.Name);
            }
            else
            {
                if (minimizeNames && member.DeclaringType.Kind != TypeKind.Interface)
                {
                    defaultName = null;
                }
                else
                {
                    defaultName = "$" + (isPreserveMemberCase ? member.Name : MakeCamelCase(member.Name));
                }
            }

            var asa = AttributeReader.ReadAttribute <AlternateSignatureAttribute>(member);

            if (asa != null)
            {
                var otherMembers = member.DeclaringTypeDefinition.Methods.Where(m => m.Name == member.Name && !AttributeReader.HasAttribute <AlternateSignatureAttribute>(m) && !AttributeReader.HasAttribute <NonScriptableAttribute>(m) && !AttributeReader.HasAttribute <InlineCodeAttribute>(m)).ToList();
                if (otherMembers.Count == 1)
                {
                    return(DeterminePreferredMemberName(otherMembers[0], minimizeNames));
                }
                else
                {
                    return(Tuple.Create(member.Name, false));                           // Error
                }
            }

            var sna = AttributeReader.ReadAttribute <ScriptNameAttribute>(member);

            if (sna != null)
            {
                string name = sna.Name;
                if (IsNamedValues(member.DeclaringTypeDefinition) && (name == "" || !name.IsValidJavaScriptIdentifier()))
                {
                    return(Tuple.Create(defaultName, false));                           // For named values enum, allow the use to specify an empty or invalid value, which will only be used as the literal value for the field, not for the name.
                }
                if (name == "" && isConstructor)
                {
                    name = "$ctor";
                }
                return(Tuple.Create(name, true));
            }

            if (isConstructor && IsImported(member.DeclaringTypeDefinition))
            {
                return(Tuple.Create("$ctor", true));
            }

            var ica = AttributeReader.ReadAttribute <InlineCodeAttribute>(member);

            if (ica != null)
            {
                if (ica.GeneratedMethodName != null)
                {
                    return(Tuple.Create(ica.GeneratedMethodName, true));
                }
            }

            if (AttributeReader.HasAttribute <PreserveCaseAttribute>(member))
            {
                return(Tuple.Create(member.Name, true));
            }

            bool preserveName = (!isConstructor && !isAccessor && (AttributeReader.HasAttribute <PreserveNameAttribute>(member) ||
                                                                   AttributeReader.HasAttribute <InstanceMethodOnFirstArgumentAttribute>(member) ||
                                                                   AttributeReader.HasAttribute <IntrinsicPropertyAttribute>(member) ||
                                                                   IsPreserveMemberNames(member.DeclaringTypeDefinition) && member.ImplementedInterfaceMembers.Count == 0 && !member.IsOverride) ||
                                 (IsSerializable(member.DeclaringTypeDefinition) && !member.IsStatic && (member is IProperty || member is IField))) ||
                                (IsNamedValues(member.DeclaringTypeDefinition) && member is IField);

            if (preserveName)
            {
                return(Tuple.Create(isPreserveMemberCase ? member.Name : MakeCamelCase(member.Name), true));
            }

            return(Tuple.Create(defaultName, false));
        }
예제 #10
0
        public static string GetModuleName(IAssembly assembly)
        {
            var mna = AttributeReader.ReadAttribute <ModuleNameAttribute>(assembly.AssemblyAttributes);

            return(mna != null && !String.IsNullOrEmpty(mna.ModuleName) ? mna.ModuleName : null);
        }
예제 #11
0
        public static bool OmitDowncasts(ICompilation compilation)
        {
            var sca = AttributeReader.ReadAttribute <ScriptSharpCompatibilityAttribute>(compilation.MainAssembly.AssemblyAttributes);

            return(sca != null && sca.OmitDowncasts);
        }
예제 #12
0
        public static bool IsPreserveMemberCase(ITypeDefinition type)
        {
            var pmca = AttributeReader.ReadAttribute <PreserveMemberCaseAttribute>(type) ?? AttributeReader.ReadAttribute <PreserveMemberCaseAttribute>(type.ParentAssembly.AssemblyAttributes);

            return(pmca != null && pmca.Preserve);
        }
예제 #13
0
            private IEnumerable<XAttribute> ReadAttributes(int skip = 0)
            {
                var textBlock = _currentText.ToString().Substring(skip);
                
                var attrReader = new AttributeReader();

                foreach (var c in textBlock)
                {
                    switch (c)
                    {
                        case '=':
                            if (attrReader.State == ReadState.ReadName)
                            {
                                attrReader.BeginReadText();
                            }
                            else
                            {
                                attrReader.Text.Append(c);
                            }
                            break;
                        case '\'':
                            if (attrReader.State == ReadState.ReadText)
                            {
                                attrReader.State = ReadState.AposOpen;
                            }
                            else
                            {
                                if (attrReader.State == ReadState.AposOpen)
                                {
                                    attrReader.State = ReadState.None;

                                    if (attrReader.SplitIndex > 0)
                                    {
                                        yield return attrReader.ReadAttribute();
                                    }
                                }
                                else
                                {
                                    attrReader.Text.Append(c);
                                }
                            }
                            break;
                        case '"':

                            if (attrReader.State == ReadState.ReadText)
                            {
                                attrReader.State = ReadState.QuoteOpen;
                            }
                            else
                            {
                                if (attrReader.State == ReadState.QuoteOpen)
                                {
                                    attrReader.State = ReadState.None;

                                    if (attrReader.SplitIndex > 0)
                                    {
                                        yield return attrReader.ReadAttribute();
                                    }
                                }
                                else
                                {
                                    attrReader.Text.Append(c);
                                }
                            }

                            break;
                        case ' ':
                            if (attrReader.State == ReadState.QuoteOpen || attrReader.State == ReadState.AposOpen)
                            {
                                attrReader.Text.Append(c);
                            }
                            else
                            {
                                if (attrReader.SplitIndex > 0)
                                {
                                    yield return attrReader.ReadAttribute();
                                }
                            }
                            break;
                        case '>':
                            if (attrReader.State == ReadState.QuoteOpen || attrReader.State == ReadState.AposOpen)
                            {
                                attrReader.Text.Append(c);
                            }
                            else
                            {
                                if (attrReader.State == ReadState.ReadText)
                                {
                                    attrReader.State = ReadState.None;

                                    if (attrReader.SplitIndex > 0)
                                    {
                                        yield return attrReader.ReadAttribute();
                                    }
                                }
                            }
                            break;
                        default:
                            if (attrReader.State == ReadState.None) attrReader.State = ReadState.ReadName;
                            attrReader.Text.Append(c);
                            break;
                    }
                }

                yield break;
            }