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), _ => {}))); }
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); }
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)); }
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); }
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); }
public static bool DoesTypeObeyTypeSystem(ITypeDefinition type) { var ia = AttributeReader.ReadAttribute <ImportedAttribute>(type); return(ia == null || ia.ObeysTypeSystem); }
/// <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)); }
public static string GetModuleName(IAssembly assembly) { var mna = AttributeReader.ReadAttribute <ModuleNameAttribute>(assembly.AssemblyAttributes); return(mna != null && !String.IsNullOrEmpty(mna.ModuleName) ? mna.ModuleName : null); }
public static bool OmitDowncasts(ICompilation compilation) { var sca = AttributeReader.ReadAttribute <ScriptSharpCompatibilityAttribute>(compilation.MainAssembly.AssemblyAttributes); return(sca != null && sca.OmitDowncasts); }
public static bool IsPreserveMemberCase(ITypeDefinition type) { var pmca = AttributeReader.ReadAttribute <PreserveMemberCaseAttribute>(type) ?? AttributeReader.ReadAttribute <PreserveMemberCaseAttribute>(type.ParentAssembly.AssemblyAttributes); return(pmca != null && pmca.Preserve); }
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; }