private JsClass GetJsClass(ITypeDefinition typeDefinition) {
			JsClass result;
			if (!_types.TryGetValue(typeDefinition, out result)) {
				if (typeDefinition.Kind == TypeKind.Struct && !_allowUserDefinedStructs) {
					var oldRegion = _errorReporter.Region;
					_errorReporter.Region = typeDefinition.Region;
					_errorReporter.Message(Messages._7998, "user-defined value type (struct)");
					_errorReporter.Region = oldRegion;
				}

				var semantics = _metadataImporter.GetTypeSemantics(typeDefinition);
				if (semantics.GenerateCode) {
					var unusableTypes = Utils.FindUsedUnusableTypes(typeDefinition.GetAllBaseTypes(), _metadataImporter).ToList();
					if (unusableTypes.Count > 0) {
						foreach (var ut in unusableTypes) {
							var oldRegion = _errorReporter.Region;
							_errorReporter.Region = typeDefinition.Region;
							_errorReporter.Message(Messages._7500, ut.FullName, typeDefinition.FullName);
							_errorReporter.Region = oldRegion;
						}
					}
					result = new JsClass(typeDefinition);
				}
				else {
					result = null;
				}
				_types[typeDefinition] = result;
			}
			return result;
		}
		private JsClass GetJsClass(ITypeDefinition typeDefinition) {
			JsClass result;
			if (!_types.TryGetValue(typeDefinition, out result)) {
				var semantics = _metadataImporter.GetTypeSemantics(typeDefinition);
				if (semantics.GenerateCode) {
					var errors = Utils.FindTypeUsageErrors(typeDefinition.GetAllBaseTypes(), _metadataImporter);
					if (errors.HasErrors) {
						var oldRegion = _errorReporter.Region;
						try {
							_errorReporter.Region = typeDefinition.Region;
							foreach (var ut in errors.UsedUnusableTypes)
								_errorReporter.Message(Messages._7500, ut.FullName, typeDefinition.FullName);
							foreach (var t in errors.MutableValueTypesBoundToTypeArguments)
								_errorReporter.Message(Messages._7539, t.FullName);
						}
						finally {
							_errorReporter.Region = oldRegion;
						}
					}
					result = new JsClass(typeDefinition);
				}
				else {
					result = null;
				}
				_types[typeDefinition] = result;
			}
			return result;
		}
		public JsClass Clone() {
			var result = new JsClass(this.CSharpTypeDefinition) {
				UnnamedConstructor = this.UnnamedConstructor
			};
			((List<JsNamedConstructor>)result.NamedConstructors).AddRange(this.NamedConstructors);
			((List<JsMethod>)result.InstanceMethods).AddRange(this.InstanceMethods);
			((List<JsMethod>)result.StaticMethods).AddRange(this.StaticMethods);
			((List<JsStatement>)result.StaticInitStatements).AddRange(this.StaticInitStatements);
			return result;
		}
Beispiel #4
0
        public JsClass Clone()
        {
            var result = new JsClass(this.CSharpTypeDefinition)
            {
                UnnamedConstructor = this.UnnamedConstructor
            };

            ((List <JsNamedConstructor>)result.NamedConstructors).AddRange(this.NamedConstructors);
            ((List <JsMethod>)result.InstanceMethods).AddRange(this.InstanceMethods);
            ((List <JsMethod>)result.StaticMethods).AddRange(this.StaticMethods);
            ((List <JsStatement>)result.StaticInitStatements).AddRange(this.StaticInitStatements);
            return(result);
        }
        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 = _attributeStore.AttributesFor(method.CSharpMember).GetAttribute<TestAttribute>();
                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, DummyRuntimeContext.Instance) } : new JsExpression[] { JsExpression.String(t.Description), _runtimeLibrary.Bind(t.Function, JsExpression.This, DummyRuntimeContext.Instance) })));
            }

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

            var result = type.Clone();
            result.InstanceMethods.Clear();
            foreach (var m in instanceMethods)
                result.InstanceMethods.Add(m);
            return result;
        }
Beispiel #6
0
 private void CompileAndAddFieldInitializerToType(JsClass jsClass, string fieldName, ITypeDefinition owningType, Expression initializer, bool isStatic)
 {
     if (isStatic) {
         jsClass.StaticInitStatements.AddRange(CreateMethodCompiler().CompileFieldInitializer(initializer.GetRegion(), JsExpression.MemberAccess(_runtimeLibrary.GetScriptType(owningType, TypeContext.UseStaticMember), fieldName), initializer));
     }
     else {
         AddInstanceInitStatements(jsClass, CreateMethodCompiler().CompileFieldInitializer(initializer.GetRegion(), JsExpression.MemberAccess(JsExpression.This, fieldName), initializer));
     }
 }
Beispiel #7
0
 private void CompileAndAddAutoPropertyMethodsToType(JsClass jsClass, IProperty property, PropertyScriptSemantics options, string backingFieldName)
 {
     if (options.GetMethod != null && options.GetMethod.GenerateCode) {
         var compiled = CreateMethodCompiler().CompileAutoPropertyGetter(property, options, backingFieldName);
         AddCompiledMethodToType(jsClass, property.Getter, options.GetMethod, new JsMethod(property.Getter, options.GetMethod.Name, new string[0], compiled));
     }
     if (options.SetMethod != null && options.SetMethod.GenerateCode) {
         var compiled = CreateMethodCompiler().CompileAutoPropertySetter(property, options, backingFieldName);
         AddCompiledMethodToType(jsClass, property.Setter, options.SetMethod, new JsMethod(property.Setter, options.SetMethod.Name, new string[0], compiled));
     }
 }
Beispiel #8
0
 private void CompileAndAddAutoEventMethodsToType(JsClass jsClass, EventDeclaration node, IEvent evt, EventScriptSemantics options, string backingFieldName)
 {
     if (options.AddMethod != null && options.AddMethod.GenerateCode) {
         var compiled = CreateMethodCompiler().CompileAutoEventAdder(evt, options, backingFieldName);
         AddCompiledMethodToType(jsClass, evt.AddAccessor, options.AddMethod, new JsMethod(evt.AddAccessor, options.AddMethod.Name, new string[0], compiled));
     }
     if (options.RemoveMethod != null && options.RemoveMethod.GenerateCode) {
         var compiled = CreateMethodCompiler().CompileAutoEventRemover(evt, options, backingFieldName);
         AddCompiledMethodToType(jsClass, evt.RemoveAccessor, options.RemoveMethod, new JsMethod(evt.RemoveAccessor, options.RemoveMethod.Name, new string[0], compiled));
     }
 }
Beispiel #9
0
 private void AddInstanceInitStatements(JsClass jsClass, IEnumerable<JsStatement> statements)
 {
     List<JsStatement> l;
     if (!_instanceInitStatements.TryGetValue(jsClass, out l))
         _instanceInitStatements[jsClass] = l = new List<JsStatement>();
     l.AddRange(statements);
 }
Beispiel #10
0
 private void AddCompiledMethodToType(JsClass jsClass, IMethod method, MethodScriptSemantics options, JsMethod jsMethod)
 {
     if ((options.Type == MethodScriptSemantics.ImplType.NormalMethod && method.IsStatic) || options.Type == MethodScriptSemantics.ImplType.StaticMethodWithThisAsFirstArgument) {
         jsClass.StaticMethods.Add(jsMethod);
     }
     else {
         jsClass.InstanceMethods.Add(jsMethod);
     }
 }
 private void AddDefaultFieldInitializerToType(JsClass jsClass, string fieldName, IMember member, IType fieldType, ITypeDefinition owningType, bool isStatic)
 {
     if (isStatic) {
         jsClass.StaticInitStatements.AddRange(CreateMethodCompiler().CompileDefaultFieldInitializer(member.Region, JsExpression.Member(_runtimeLibrary.GetScriptType(owningType, TypeContext.UseStaticMember), fieldName), fieldType));
     }
     else {
         AddInstanceInitStatements(jsClass, CreateMethodCompiler().CompileDefaultFieldInitializer(member.Region, JsExpression.Member(JsExpression.This, fieldName), fieldType));
     }
 }
Beispiel #12
0
 private List<JsStatement> TryGetInstanceInitStatements(JsClass jsClass)
 {
     List<JsStatement> l;
     if (_instanceInitStatements.TryGetValue(jsClass, out l))
         return l;
     else
         return new List<JsStatement>();
 }
Beispiel #13
0
 private void MaybeCompileAndAddConstructorToType(JsClass jsClass, ConstructorDeclaration node, IMethod constructor, ConstructorScriptSemantics options)
 {
     if (options.GenerateCode) {
         var mc = CreateMethodCompiler();
         var compiled = mc.CompileConstructor(node, constructor, TryGetInstanceInitStatements(jsClass), options);
         OnMethodCompiled(constructor, compiled, mc);
         AddCompiledConstructorToType(jsClass, constructor, options, compiled);
     }
 }
Beispiel #14
0
        private JsClass GetJsClass(ITypeDefinition typeDefinition)
        {
            JsClass result;
            if (!_types.TryGetValue(typeDefinition, out result)) {
                var semantics = _metadataImporter.GetTypeSemantics(typeDefinition);
                if (semantics.GenerateCode) {
                    var unusableTypes = Utils.FindUsedUnusableTypes(typeDefinition.GetAllBaseTypes(), _metadataImporter).ToList();
                    if (unusableTypes.Count > 0) {
                        foreach (var ut in unusableTypes) {
                            var oldRegion = _errorReporter.Region;
                            _errorReporter.Region = typeDefinition.Region;
                            _errorReporter.Message(7500, ut.FullName, typeDefinition.FullName);
                            _errorReporter.Region = oldRegion;
                        }

                        result = new JsClass(typeDefinition, "X", ConvertClassType(typeDefinition.Kind), new string[0], null, null);
                    }
                    else {
                        var baseTypes    = typeDefinition.GetAllBaseTypes().Where(t => _runtimeLibrary.GetScriptType(t, TypeContext.GenericArgument) != null).ToList();

                        var baseClass    = typeDefinition.Kind != TypeKind.Interface ? _runtimeLibrary.GetScriptType(baseTypes.Last(t => !t.GetDefinition().Equals(typeDefinition) && t.Kind == TypeKind.Class), TypeContext.Inheritance) : null;    // NRefactory bug/feature: Interfaces are reported as having System.Object as their base type.
                        var interfaces   = baseTypes.Where(t => !t.GetDefinition().Equals(typeDefinition) && t.Kind == TypeKind.Interface).Select(t => _runtimeLibrary.GetScriptType(t, TypeContext.Inheritance)).Where(t => t != null).ToList();
                        var typeArgNames = semantics.IgnoreGenericArguments ? null : typeDefinition.TypeParameters.Select(a => _namer.GetTypeParameterName(a)).ToList();
                        result = new JsClass(typeDefinition, semantics.Name, ConvertClassType(typeDefinition.Kind), typeArgNames, baseClass, interfaces);
                    }
                }
                else {
                    result = null;
                }
                _types[typeDefinition] = result;
            }
            return result;
        }
		private void CompileAndAddFieldInitializerToType(JsClass jsClass, string fieldName, ITypeDefinition owningType, Expression initializer, bool isStatic) {
			if (isStatic) {
				jsClass.StaticInitStatements.AddRange(CreateMethodCompiler().CompileFieldInitializer(initializer.GetRegion(), JsExpression.Member(_runtimeLibrary.InstantiateType(Utils.SelfParameterize(owningType), this), fieldName), initializer, owningType));
			}
			else {
				AddInstanceInitStatements(jsClass, CreateMethodCompiler().CompileFieldInitializer(initializer.GetRegion(), JsExpression.Member(JsExpression.This, fieldName), initializer, owningType));
			}
		}
		private void AddDefaultFieldInitializerToType(JsClass jsClass, string fieldName, IMember member, IType fieldType, ITypeDefinition owningType, bool isStatic) {
			if (isStatic) {
				jsClass.StaticInitStatements.AddRange(CreateMethodCompiler().CompileDefaultFieldInitializer(member.Region, JsExpression.Member(_runtimeLibrary.InstantiateType(Utils.SelfParameterize(owningType), this), fieldName), fieldType, member.DeclaringTypeDefinition));
			}
			else {
				AddInstanceInitStatements(jsClass, CreateMethodCompiler().CompileDefaultFieldInitializer(member.Region, JsExpression.Member(JsExpression.This, fieldName), fieldType, member.DeclaringTypeDefinition));
			}
		}
		public virtual IEnumerable<JsStatement> GetStaticInitStatements(JsClass type) {
			return _prev.GetStaticInitStatements(type);
		}
Beispiel #18
0
 private void MaybeAddDefaultConstructorToType(JsClass jsClass, IMethod constructor)
 {
     var options = _metadataImporter.GetConstructorSemantics(constructor);
     if (options.GenerateCode) {
         var mc = CreateMethodCompiler();
         var compiled = mc.CompileDefaultConstructor(constructor, TryGetInstanceInitStatements(jsClass), options);
         OnMethodCompiled(constructor, compiled, mc);
         AddCompiledConstructorToType(jsClass, constructor, options, compiled);
     }
 }
        private void AddClassMembers(JsClass c, JsExpression typeRef, ICompilation compilation, List<JsStatement> stmts)
        {
            ICollection<JsMethod> instanceMethods;
            if (_metadataImporter.IsTestFixture(c.CSharpTypeDefinition)) {
                var tests = new List<Tuple<string, string, bool, int?, JsFunctionDefinitionExpression>>();
                var instanceMethodList = new List<JsMethod>();
                foreach (var m in c.InstanceMethods) {
                    var td = (m.CSharpMember is IMethod ? _metadataImporter.GetTestData((IMethod)m.CSharpMember) : null);
                    if (td != null) {
                        tests.Add(Tuple.Create(td.Description, td.Category, td.IsAsync, td.ExpectedAssertionCount, m.Definition));
                    }
                    else {
                        instanceMethodList.Add(m);
                    }
                }
                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.Identifier("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) } : new JsExpression[] { JsExpression.String(t.Description), _runtimeLibrary.Bind(t.Function, JsExpression.This) })));
                }

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

                instanceMethods = instanceMethodList;
            }
            else {
                instanceMethods = c.InstanceMethods;
            }

            if (instanceMethods.Count > 0) {
                stmts.Add(new JsExpressionStatement(JsExpression.Assign(JsExpression.MemberAccess(typeRef, Prototype), JsExpression.ObjectLiteral(instanceMethods.Select(m => new JsObjectLiteralProperty(m.Name, m.Definition != null ? RewriteMethod(m) : JsExpression.Null))))));
            }

            if (c.NamedConstructors.Count > 0) {
                stmts.AddRange(c.NamedConstructors.Select(m => new JsExpressionStatement(JsExpression.Assign(JsExpression.MemberAccess(typeRef, m.Name), m.Definition))));
                stmts.Add(new JsExpressionStatement(c.NamedConstructors.Reverse().Aggregate((JsExpression)JsExpression.MemberAccess(typeRef, Prototype), (right, ctor) => JsExpression.Assign(JsExpression.MemberAccess(JsExpression.MemberAccess(typeRef, ctor.Name), Prototype), right))));	// This generates a statement like {C}.ctor1.prototype = {C}.ctor2.prototype = {C}.prototoype
            }

            stmts.AddRange(c.StaticMethods.Select(m => new JsExpressionStatement(JsExpression.Assign(JsExpression.MemberAccess(typeRef, m.Name), RewriteMethod(m)))));

            if (c.TypeArgumentNames.Count > 0) {
                if (c.ClassType == JsClass.ClassTypeEnum.Interface) {
                    stmts.Add(new JsExpressionStatement(JsExpression.Invocation(JsExpression.MemberAccess(typeRef, RegisterGenericInterfaceInstance),
                                                                                typeRef,
                                                                                new JsTypeReferenceExpression(compilation.MainAssembly, c.Name),
                                                                                JsExpression.ArrayLiteral(c.TypeArgumentNames.Select(JsExpression.Identifier)),
                                                                                JsExpression.FunctionDefinition(new string[0], new JsReturnStatement(JsExpression.ArrayLiteral(c.ImplementedInterfaces))))));
                }
                else {
                    stmts.Add(new JsExpressionStatement(JsExpression.Invocation(JsExpression.MemberAccess(typeRef, RegisterGenericClassInstance),
                                                                                typeRef,
                                                                                new JsTypeReferenceExpression(compilation.MainAssembly, c.Name),
                                                                                JsExpression.ArrayLiteral(c.TypeArgumentNames.Select(JsExpression.Identifier)),
                                                                                JsExpression.FunctionDefinition(new string[0], new JsReturnStatement(c.BaseClass)),
                                                                                JsExpression.FunctionDefinition(new string[0], new JsReturnStatement(JsExpression.ArrayLiteral(c.ImplementedInterfaces))))));
                }
            }
        }
Beispiel #20
0
 private void MaybeCompileAndAddMethodToType(JsClass jsClass, EntityDeclaration node, BlockStatement body, IMethod method, MethodScriptSemantics options)
 {
     if (options.GenerateCode) {
         var typeParamNames = options.IgnoreGenericArguments ? (IEnumerable<string>)new string[0] : method.TypeParameters.Select(tp => _namer.GetTypeParameterName(tp)).ToList();
         JsMethod jsMethod;
         if (method.IsAbstract) {
             jsMethod = new JsMethod(method, options.Name, typeParamNames, null);
         }
         else {
             var compiled = CompileMethod(node, body, method, options);
             jsMethod = new JsMethod(method, options.Name, typeParamNames, compiled);
         }
         AddCompiledMethodToType(jsClass, method, options, jsMethod);
     }
 }
        private JsStatement GenerateResourcesClass(JsClass c)
        {
            var fields = c.StaticInitStatements
                          .OfType<JsExpressionStatement>()
                          .Select(s => s.Expression)
                          .OfType<JsBinaryExpression>()
                          .Where(expr => expr.NodeType == ExpressionNodeType.Assign && expr.Left is JsMemberAccessExpression)
                          .Select(expr => new { Name = ((JsMemberAccessExpression)expr.Left).Member, Value = expr.Right });

            return new JsExpressionStatement(JsExpression.Assign(new JsTypeReferenceExpression(c.CSharpTypeDefinition.ParentAssembly, c.Name), JsExpression.ObjectLiteral(fields.Select(f => new JsObjectLiteralProperty(f.Name, f.Value)))));
        }
		IEnumerable<JsStatement> IOOPEmulator.GetStaticInitStatements(JsClass type) {
			return GetStaticInitStatements(type);
		}
Beispiel #23
0
        private void AddCompiledConstructorToType(JsClass jsClass, IMethod constructor, ConstructorScriptSemantics options, JsFunctionDefinitionExpression jsConstructor)
        {
            switch (options.Type) {
                case ConstructorScriptSemantics.ImplType.UnnamedConstructor:
                    if (jsClass.UnnamedConstructor != null) {
                        _errorReporter.Region = constructor.Region;
                        _errorReporter.Message(7501, constructor.DeclaringType.FullName);
                    }
                    else {
                        jsClass.UnnamedConstructor = jsConstructor;
                    }
                    break;
                case ConstructorScriptSemantics.ImplType.NamedConstructor:
                    jsClass.NamedConstructors.Add(new JsNamedConstructor(options.Name, jsConstructor));
                    break;

                case ConstructorScriptSemantics.ImplType.StaticMethod:
                    jsClass.StaticMethods.Add(new JsMethod(constructor, options.Name, new string[0], jsConstructor));
                    break;
            }
        }