public JsFunctionDefinitionExpression CompileAutoPropertySetter(IProperty property, PropertyScriptSemantics impl, string backingFieldName)
        {
            try {
                string valueName = _namer.GetVariableName(property.Setter.Parameters[0].Name, new HashSet <string>(property.DeclaringTypeDefinition.TypeParameters.Select(p => _namer.GetTypeParameterName(p))));
                CreateCompilationContext(null, null, property.DeclaringTypeDefinition, null);

                if (property.IsStatic)
                {
                    var jsType = _runtimeLibrary.InstantiateType(Utils.SelfParameterize(property.DeclaringTypeDefinition), _statementCompiler);
                    return(JsExpression.FunctionDefinition(new[] { valueName }, JsExpression.Assign(JsExpression.Member(jsType, backingFieldName), JsExpression.Identifier(valueName))));
                }
                else if (impl.SetMethod.Type == MethodScriptSemantics.ImplType.StaticMethodWithThisAsFirstArgument)
                {
                    return(JsExpression.FunctionDefinition(new[] { _namer.ThisAlias, valueName }, JsExpression.Assign(JsExpression.Member(JsExpression.Identifier(_namer.ThisAlias), backingFieldName), JsExpression.Identifier(valueName))));
                }
                else
                {
                    return(JsExpression.FunctionDefinition(new[] { valueName }, JsExpression.Assign(JsExpression.Member(JsExpression.This, backingFieldName), JsExpression.Identifier(valueName))));
                }
            }
            catch (Exception ex) {
                _errorReporter.Region = property.Setter.Region;
                _errorReporter.InternalError(ex);
                return(JsExpression.FunctionDefinition(new string[0], JsStatement.EmptyBlock));
            }
        }
 private static ExpressionCompileResult Compile(ResolveResult rr, ITypeDefinition currentType, IMethod currentMethod, ICompilation compilation, IMetadataImporter metadataImporter, INamer namer, IRuntimeLibrary runtimeLibrary, IErrorReporter errorReporter, bool returnValueIsImportant, Dictionary <IVariable, VariableData> variables, ISet <string> usedVariableNames)
 {
     variables         = variables ?? new Dictionary <IVariable, VariableData>();
     usedVariableNames = usedVariableNames ?? new HashSet <string>();
     return(new ExpressionCompiler(compilation,
                                   metadataImporter,
                                   namer,
                                   runtimeLibrary,
                                   errorReporter,
                                   variables,
                                   new Dictionary <LambdaResolveResult, NestedFunctionData>(),
                                   t => {
         string name = namer.GetVariableName(null, usedVariableNames);
         IVariable variable = new SimpleVariable(t, "temporary", DomRegion.Empty);
         variables[variable] = new VariableData(name, null, false);
         usedVariableNames.Add(name);
         return variable;
     },
                                   _ => { throw new Exception("Cannot compile nested functions here"); },
                                   null,
                                   new NestedFunctionContext(EmptyList <IVariable> .Instance),
                                   null,
                                   currentMethod,
                                   currentType
                                   ).Compile(rr, returnValueIsImportant));
 }
Exemple #3
0
            private string GetModuleAlias(string moduleName)
            {
                string result;

                if (_moduleAliases.TryGetValue(moduleName, out result))
                {
                    return(result);
                }

                result = "";
                for (int i = 0; i < moduleName.Length; i++)
                {
                    char ch = moduleName[i];
                    if (ch == '_' || ch == '$' || char.IsLetter(ch) || (i > 0 && char.IsDigit(ch)))
                    {
                        result += ch;
                    }
                }
                if (result == "")
                {
                    result = "_";
                }

                result = _namer.GetVariableName(result, _usedSymbols);
                _usedSymbols.Add(result);

                return(_moduleAliases[moduleName] = result);
            }
Exemple #4
0
        private void AddVariable(IVariable v, bool isUsedByReference = false)
        {
            string n = _namer.GetVariableName(v.Name, _usedNames);

            _usedNames.Add(n);
            _result.Add(v, new VariableData(n, _currentMethod, isUsedByReference));
            if (_isInsideLoop)
            {
                _variablesDeclaredInsideLoop.Add(v);
            }
        }
        private static JsExpression ConstructMemberInfo(IMember m, ICompilation compilation, IMetadataImporter metadataImporter, INamer namer, IRuntimeLibrary runtimeLibrary, IErrorReporter errorReporter, Func <IType, JsExpression> instantiateType, bool includeDeclaringType, MethodScriptSemantics semanticsIfAccessor)
        {
            if (m is IMethod && ((IMethod)m).IsConstructor)
            {
                return(ConstructConstructorInfo((IMethod)m, compilation, metadataImporter, namer, runtimeLibrary, errorReporter, instantiateType, includeDeclaringType));
            }

            var properties = GetCommonMemberInfoProperties(m, compilation, metadataImporter, namer, runtimeLibrary, errorReporter, instantiateType, includeDeclaringType);

            if (m.IsStatic)
            {
                properties.Add(new JsObjectLiteralProperty("isStatic", JsExpression.True));
            }

            if (m is IMethod)
            {
                var method = (IMethod)m;
                var sem    = semanticsIfAccessor ?? metadataImporter.GetMethodSemantics(method);
                if (sem.Type != MethodScriptSemantics.ImplType.NormalMethod && sem.Type != MethodScriptSemantics.ImplType.StaticMethodWithThisAsFirstArgument && sem.Type != MethodScriptSemantics.ImplType.InlineCode)
                {
                    errorReporter.Message(Messages._7201, m.FullName, "method");
                    return(JsExpression.Null);
                }
                if ((sem.Type == MethodScriptSemantics.ImplType.NormalMethod || sem.Type == MethodScriptSemantics.ImplType.StaticMethodWithThisAsFirstArgument) && sem.ExpandParams)
                {
                    properties.Add(new JsObjectLiteralProperty("exp", JsExpression.True));
                }

                properties.Add(new JsObjectLiteralProperty("type", JsExpression.Number((int)MemberTypes.Method)));
                if (sem.Type == MethodScriptSemantics.ImplType.InlineCode)
                {
                    var usedNames  = new HashSet <string>();
                    var parameters = new List <IVariable>();
                    var variables  = new Dictionary <IVariable, VariableData>();
                    var arguments  = new List <ResolveResult>();
                    foreach (var p in method.Parameters)
                    {
                        string name = namer.GetVariableName(p.Name, usedNames);
                        usedNames.Add(name);
                        var variable = new SimpleVariable(p.Type, p.Name, DomRegion.Empty);
                        parameters.Add(variable);
                        variables.Add(variable, new VariableData(name, null, false));
                        arguments.Add(new LocalResolveResult(variable));
                    }
                    var tokens = InlineCodeMethodCompiler.Tokenize(method, sem.LiteralCode, _ => {});

                    var compileResult = Compile(CreateMethodInvocationResolveResult(method, method.IsStatic ? (ResolveResult) new TypeResolveResult(method.DeclaringType) : new ThisResolveResult(method.DeclaringType), arguments), method.DeclaringTypeDefinition, method, compilation, metadataImporter, namer, runtimeLibrary, errorReporter, true, variables, usedNames);
                    var definition    = JsExpression.FunctionDefinition(parameters.Select(p => variables[p].Name), JsStatement.Block(compileResult.AdditionalStatements.Concat(new[] { JsStatement.Return(compileResult.Expression) })));

                    if (tokens.Any(t => t.Type == InlineCodeToken.TokenType.TypeParameter && t.OwnerType == SymbolKind.Method))
                    {
                        definition = JsExpression.FunctionDefinition(method.TypeParameters.Select(namer.GetTypeParameterName), JsStatement.Return(definition));
                        properties.Add(new JsObjectLiteralProperty("tpcount", JsExpression.Number(method.TypeParameters.Count)));
                    }
                    properties.Add(new JsObjectLiteralProperty("def", definition));
                }
                else
                {
                    if (IsJsGeneric(method, metadataImporter))
                    {
                        properties.Add(new JsObjectLiteralProperty("tpcount", JsExpression.Number(method.TypeParameters.Count)));
                    }
                    if (sem.Type == MethodScriptSemantics.ImplType.StaticMethodWithThisAsFirstArgument)
                    {
                        properties.Add(new JsObjectLiteralProperty("sm", JsExpression.True));
                    }
                    properties.Add(new JsObjectLiteralProperty("sname", JsExpression.String(sem.Name)));
                }
                properties.Add(new JsObjectLiteralProperty("returnType", instantiateType(method.ReturnType)));
                properties.Add(new JsObjectLiteralProperty("params", JsExpression.ArrayLiteral(method.Parameters.Select(p => instantiateType(p.Type)))));
            }
            else if (m is IField)
            {
                var field = (IField)m;
                var sem   = metadataImporter.GetFieldSemantics(field);
                if (sem.Type != FieldScriptSemantics.ImplType.Field)
                {
                    errorReporter.Message(Messages._7201, m.FullName, "field");
                    return(JsExpression.Null);
                }
                properties.Add(new JsObjectLiteralProperty("type", JsExpression.Number((int)MemberTypes.Field)));
                properties.Add(new JsObjectLiteralProperty("returnType", instantiateType(field.ReturnType)));
                properties.Add(new JsObjectLiteralProperty("sname", JsExpression.String(sem.Name)));
            }
            else if (m is IProperty)
            {
                var prop = (IProperty)m;
                var sem  = metadataImporter.GetPropertySemantics(prop);
                properties.Add(new JsObjectLiteralProperty("type", JsExpression.Number((int)MemberTypes.Property)));
                properties.Add(new JsObjectLiteralProperty("returnType", instantiateType(prop.ReturnType)));
                if (prop.Parameters.Count > 0)
                {
                    properties.Add(new JsObjectLiteralProperty("params", JsExpression.ArrayLiteral(prop.Parameters.Select(p => instantiateType(p.Type)))));
                }

                switch (sem.Type)
                {
                case PropertyScriptSemantics.ImplType.GetAndSetMethods:
                    if (sem.GetMethod != null && sem.GetMethod.Type != MethodScriptSemantics.ImplType.NormalMethod && sem.GetMethod.Type != MethodScriptSemantics.ImplType.StaticMethodWithThisAsFirstArgument && sem.GetMethod.Type != MethodScriptSemantics.ImplType.InlineCode)
                    {
                        errorReporter.Message(Messages._7202, m.FullName, "property", "getter");
                        return(JsExpression.Null);
                    }
                    if (sem.SetMethod != null && sem.SetMethod.Type != MethodScriptSemantics.ImplType.NormalMethod && sem.SetMethod.Type != MethodScriptSemantics.ImplType.StaticMethodWithThisAsFirstArgument && sem.SetMethod.Type != MethodScriptSemantics.ImplType.InlineCode)
                    {
                        errorReporter.Message(Messages._7202, m.FullName, "property", "setter");
                        return(JsExpression.Null);
                    }
                    if (sem.GetMethod != null)
                    {
                        properties.Add(new JsObjectLiteralProperty("getter", ConstructMemberInfo(prop.Getter, compilation, metadataImporter, namer, runtimeLibrary, errorReporter, instantiateType, includeDeclaringType, sem.GetMethod)));
                    }
                    if (sem.SetMethod != null)
                    {
                        properties.Add(new JsObjectLiteralProperty("setter", ConstructMemberInfo(prop.Setter, compilation, metadataImporter, namer, runtimeLibrary, errorReporter, instantiateType, includeDeclaringType, sem.SetMethod)));
                    }
                    break;

                case PropertyScriptSemantics.ImplType.Field:
                    if (prop.CanGet)
                    {
                        properties.Add(new JsObjectLiteralProperty("getter", ConstructFieldPropertyAccessor(prop.Getter, compilation, metadataImporter, namer, runtimeLibrary, errorReporter, sem.FieldName, instantiateType, isGetter: true, includeDeclaringType: includeDeclaringType)));
                    }
                    if (prop.CanSet)
                    {
                        properties.Add(new JsObjectLiteralProperty("setter", ConstructFieldPropertyAccessor(prop.Setter, compilation, metadataImporter, namer, runtimeLibrary, errorReporter, sem.FieldName, instantiateType, isGetter: false, includeDeclaringType: includeDeclaringType)));
                    }
                    properties.Add(new JsObjectLiteralProperty("fname", JsExpression.String(sem.FieldName)));
                    break;

                default:
                    errorReporter.Message(Messages._7201, m.FullName, "property");
                    return(JsExpression.Null);
                }
            }
            else if (m is IEvent)
            {
                var evt = (IEvent)m;
                var sem = metadataImporter.GetEventSemantics(evt);
                if (sem.Type != EventScriptSemantics.ImplType.AddAndRemoveMethods)
                {
                    errorReporter.Message(Messages._7201, m.FullName, "event");
                    return(JsExpression.Null);
                }
                if (sem.AddMethod.Type != MethodScriptSemantics.ImplType.NormalMethod && sem.AddMethod.Type != MethodScriptSemantics.ImplType.StaticMethodWithThisAsFirstArgument && sem.AddMethod.Type != MethodScriptSemantics.ImplType.InlineCode)
                {
                    errorReporter.Message(Messages._7202, m.FullName, "event", "add accessor");
                    return(JsExpression.Null);
                }
                if (sem.RemoveMethod.Type != MethodScriptSemantics.ImplType.NormalMethod && sem.RemoveMethod.Type != MethodScriptSemantics.ImplType.StaticMethodWithThisAsFirstArgument && sem.RemoveMethod.Type != MethodScriptSemantics.ImplType.InlineCode)
                {
                    errorReporter.Message(Messages._7202, m.FullName, "event", "remove accessor");
                    return(JsExpression.Null);
                }

                properties.Add(new JsObjectLiteralProperty("type", JsExpression.Number((int)MemberTypes.Event)));
                properties.Add(new JsObjectLiteralProperty("adder", ConstructMemberInfo(evt.AddAccessor, compilation, metadataImporter, namer, runtimeLibrary, errorReporter, instantiateType, includeDeclaringType, sem.AddMethod)));
                properties.Add(new JsObjectLiteralProperty("remover", ConstructMemberInfo(evt.RemoveAccessor, compilation, metadataImporter, namer, runtimeLibrary, errorReporter, instantiateType, includeDeclaringType, sem.RemoveMethod)));
            }
            else
            {
                throw new ArgumentException("Invalid member " + m);
            }

            return(JsExpression.ObjectLiteral(properties));
        }
        private static JsExpression ConstructConstructorInfo(IMethod constructor, ICompilation compilation, IMetadataImporter metadataImporter, INamer namer, IRuntimeLibrary runtimeLibrary, IErrorReporter errorReporter, Func <IType, JsExpression> instantiateType, bool includeDeclaringType)
        {
            var properties = GetCommonMemberInfoProperties(constructor, compilation, metadataImporter, namer, runtimeLibrary, errorReporter, instantiateType, includeDeclaringType);

            var sem = metadataImporter.GetConstructorSemantics(constructor);

            if (sem.Type == ConstructorScriptSemantics.ImplType.NotUsableFromScript)
            {
                errorReporter.Message(Messages._7200, constructor.FullName);
                return(JsExpression.Null);
            }
            properties.Add(new JsObjectLiteralProperty("type", JsExpression.Number((int)MemberTypes.Constructor)));
            properties.Add(new JsObjectLiteralProperty("params", JsExpression.ArrayLiteral(constructor.Parameters.Select(p => instantiateType(p.Type)))));
            if (sem.Type == ConstructorScriptSemantics.ImplType.NamedConstructor || sem.Type == ConstructorScriptSemantics.ImplType.StaticMethod)
            {
                properties.Add(new JsObjectLiteralProperty("sname", JsExpression.String(sem.Name)));
            }
            if (sem.Type == ConstructorScriptSemantics.ImplType.StaticMethod)
            {
                properties.Add(new JsObjectLiteralProperty("sm", JsExpression.True));
            }
            if ((sem.Type == ConstructorScriptSemantics.ImplType.UnnamedConstructor || sem.Type == ConstructorScriptSemantics.ImplType.NamedConstructor || sem.Type == ConstructorScriptSemantics.ImplType.StaticMethod) && sem.ExpandParams)
            {
                properties.Add(new JsObjectLiteralProperty("exp", JsExpression.True));
            }
            if (sem.Type == ConstructorScriptSemantics.ImplType.Json || sem.Type == ConstructorScriptSemantics.ImplType.InlineCode)
            {
                var usedNames  = new HashSet <string>();
                var parameters = new List <IVariable>();
                var variables  = new Dictionary <IVariable, VariableData>();
                IList <ResolveResult> constructorParameters = null;
                IList <ResolveResult> initializerStatements = null;
                if (sem.Type == ConstructorScriptSemantics.ImplType.Json && constructor.DeclaringType.Kind == TypeKind.Anonymous)
                {
                    initializerStatements = new List <ResolveResult>();
                    foreach (var p in constructor.DeclaringType.GetProperties())
                    {
                        string paramName = MakeCamelCase(p.Name);
                        string name      = namer.GetVariableName(paramName, usedNames);
                        usedNames.Add(name);
                        var variable = new SimpleVariable(p.ReturnType, paramName, DomRegion.Empty);
                        parameters.Add(variable);
                        variables.Add(variable, new VariableData(name, null, false));
                        initializerStatements.Add(new OperatorResolveResult(p.ReturnType, ExpressionType.Assign, new MemberResolveResult(new InitializedObjectResolveResult(constructor.DeclaringType), p), new LocalResolveResult(variable)));
                    }
                }
                else
                {
                    constructorParameters = new List <ResolveResult>();
                    foreach (var p in constructor.Parameters)
                    {
                        string name = namer.GetVariableName(p.Name, usedNames);
                        usedNames.Add(name);
                        var variable = new SimpleVariable(p.Type, p.Name, DomRegion.Empty);
                        parameters.Add(variable);
                        variables.Add(variable, new VariableData(name, null, false));
                        constructorParameters.Add(new LocalResolveResult(variable));
                    }
                }
                var compileResult = CompileConstructorInvocation(constructor, initializerStatements, constructor.DeclaringTypeDefinition, constructor, constructorParameters, compilation, metadataImporter, namer, runtimeLibrary, errorReporter, variables, usedNames);
                var definition    = JsExpression.FunctionDefinition(parameters.Select(p => variables[p].Name), JsStatement.Block(compileResult.AdditionalStatements.Concat(new[] { JsStatement.Return(compileResult.Expression) })));
                properties.Add(new JsObjectLiteralProperty("def", definition));
            }
            return(JsExpression.ObjectLiteral(properties));
        }
		private static JsExpression ConstructMemberInfo(IMember m, ICompilation compilation, IMetadataImporter metadataImporter, INamer namer, IRuntimeLibrary runtimeLibrary, IErrorReporter errorReporter, Func<IType, JsExpression> instantiateType, bool includeDeclaringType, MethodScriptSemantics semanticsIfAccessor) {
			if (m is IMethod && ((IMethod)m).IsConstructor)
				return ConstructConstructorInfo((IMethod)m, compilation, metadataImporter, namer, runtimeLibrary, errorReporter, instantiateType, includeDeclaringType);

			var properties = GetCommonMemberInfoProperties(m, compilation, metadataImporter, namer, runtimeLibrary, errorReporter, instantiateType, includeDeclaringType);
			if (m.IsStatic)
				properties.Add(new JsObjectLiteralProperty("isStatic", JsExpression.True));

			if (m is IMethod) {
				var method = (IMethod)m;
				var sem = semanticsIfAccessor ?? metadataImporter.GetMethodSemantics(method);
				if (sem.Type != MethodScriptSemantics.ImplType.NormalMethod && sem.Type != MethodScriptSemantics.ImplType.StaticMethodWithThisAsFirstArgument && sem.Type != MethodScriptSemantics.ImplType.InlineCode) {
					errorReporter.Message(Messages._7201, m.FullName, "method");
					return JsExpression.Null;
				}
				if ((sem.Type == MethodScriptSemantics.ImplType.NormalMethod || sem.Type == MethodScriptSemantics.ImplType.StaticMethodWithThisAsFirstArgument) && sem.ExpandParams)
					properties.Add(new JsObjectLiteralProperty("exp", JsExpression.True));

				properties.Add(new JsObjectLiteralProperty("type", JsExpression.Number((int)MemberTypes.Method)));
				if (sem.Type == MethodScriptSemantics.ImplType.InlineCode) {
					var usedNames = new HashSet<string>();
					var parameters = new List<IVariable>();
					var variables = new Dictionary<IVariable, VariableData>();
					var arguments = new List<ResolveResult>();
					foreach (var p in method.Parameters) {
						string name = namer.GetVariableName(p.Name, usedNames);
						usedNames.Add(name);
						var variable = new SimpleVariable(p.Type, p.Name, DomRegion.Empty);
						parameters.Add(variable);
						variables.Add(variable, new VariableData(name, null, false));
						arguments.Add(new LocalResolveResult(variable));
					}
					var tokens = InlineCodeMethodCompiler.Tokenize(method, sem.LiteralCode, _ => {});

					var compileResult = Compile(CreateMethodInvocationResolveResult(method, method.IsStatic ? (ResolveResult)new TypeResolveResult(method.DeclaringType) : new ThisResolveResult(method.DeclaringType), arguments), method.DeclaringTypeDefinition, method, compilation, metadataImporter, namer, runtimeLibrary, errorReporter, true, variables, usedNames);
					var definition = JsExpression.FunctionDefinition(parameters.Select(p => variables[p].Name), JsStatement.Block(compileResult.AdditionalStatements.Concat(new[] { JsStatement.Return(compileResult.Expression) })));

					if (tokens.Any(t => t.Type == InlineCodeToken.TokenType.TypeParameter && t.OwnerType == SymbolKind.Method)) {
						definition = JsExpression.FunctionDefinition(method.TypeParameters.Select(namer.GetTypeParameterName), JsStatement.Return(definition));
						properties.Add(new JsObjectLiteralProperty("tpcount", JsExpression.Number(method.TypeParameters.Count)));
					}
					properties.Add(new JsObjectLiteralProperty("def", definition));
				}
				else {
					if (IsJsGeneric(method, metadataImporter)) {
						properties.Add(new JsObjectLiteralProperty("tpcount", JsExpression.Number(method.TypeParameters.Count)));
					}
					if (sem.Type == MethodScriptSemantics.ImplType.StaticMethodWithThisAsFirstArgument) {
						properties.Add(new JsObjectLiteralProperty("sm", JsExpression.True));
					}
					properties.Add(new JsObjectLiteralProperty("sname", JsExpression.String(sem.Name)));
				}
				properties.Add(new JsObjectLiteralProperty("returnType", instantiateType(method.ReturnType)));
				properties.Add(new JsObjectLiteralProperty("params", JsExpression.ArrayLiteral(method.Parameters.Select(p => instantiateType(p.Type)))));
			}
			else if (m is IField) {
				var field = (IField)m;
				var sem = metadataImporter.GetFieldSemantics(field);
				if (sem.Type != FieldScriptSemantics.ImplType.Field) {
					errorReporter.Message(Messages._7201, m.FullName, "field");
					return JsExpression.Null;
				}
				properties.Add(new JsObjectLiteralProperty("type", JsExpression.Number((int)MemberTypes.Field)));
				properties.Add(new JsObjectLiteralProperty("returnType", instantiateType(field.ReturnType)));
				properties.Add(new JsObjectLiteralProperty("sname", JsExpression.String(sem.Name)));
			}
			else if (m is IProperty) {
				var prop = (IProperty)m;
				var sem = metadataImporter.GetPropertySemantics(prop);
				properties.Add(new JsObjectLiteralProperty("type", JsExpression.Number((int)MemberTypes.Property)));
				properties.Add(new JsObjectLiteralProperty("returnType", instantiateType(prop.ReturnType)));
				if (prop.Parameters.Count > 0)
					properties.Add(new JsObjectLiteralProperty("params", JsExpression.ArrayLiteral(prop.Parameters.Select(p => instantiateType(p.Type)))));

				switch (sem.Type) {
					case PropertyScriptSemantics.ImplType.GetAndSetMethods:
						if (sem.GetMethod != null && sem.GetMethod.Type != MethodScriptSemantics.ImplType.NormalMethod && sem.GetMethod.Type != MethodScriptSemantics.ImplType.StaticMethodWithThisAsFirstArgument && sem.GetMethod.Type != MethodScriptSemantics.ImplType.InlineCode) {
							errorReporter.Message(Messages._7202, m.FullName, "property", "getter");
							return JsExpression.Null;
						}
						if (sem.SetMethod != null && sem.SetMethod.Type != MethodScriptSemantics.ImplType.NormalMethod && sem.SetMethod.Type != MethodScriptSemantics.ImplType.StaticMethodWithThisAsFirstArgument && sem.SetMethod.Type != MethodScriptSemantics.ImplType.InlineCode) {
							errorReporter.Message(Messages._7202, m.FullName, "property", "setter");
							return JsExpression.Null;
						}
						if (sem.GetMethod != null)
							properties.Add(new JsObjectLiteralProperty("getter", ConstructMemberInfo(prop.Getter, compilation, metadataImporter, namer, runtimeLibrary, errorReporter, instantiateType, includeDeclaringType, sem.GetMethod)));
						if (sem.SetMethod != null)
							properties.Add(new JsObjectLiteralProperty("setter", ConstructMemberInfo(prop.Setter, compilation, metadataImporter, namer, runtimeLibrary, errorReporter, instantiateType, includeDeclaringType, sem.SetMethod)));
						break;
					case PropertyScriptSemantics.ImplType.Field:
						if (prop.CanGet)
							properties.Add(new JsObjectLiteralProperty("getter", ConstructFieldPropertyAccessor(prop.Getter, compilation, metadataImporter, namer, runtimeLibrary, errorReporter, sem.FieldName, instantiateType, isGetter: true, includeDeclaringType: includeDeclaringType)));
						if (prop.CanSet)
							properties.Add(new JsObjectLiteralProperty("setter", ConstructFieldPropertyAccessor(prop.Setter, compilation, metadataImporter, namer, runtimeLibrary, errorReporter, sem.FieldName, instantiateType, isGetter: false, includeDeclaringType: includeDeclaringType)));
						properties.Add(new JsObjectLiteralProperty("fname", JsExpression.String(sem.FieldName)));
						break;
					default:
						errorReporter.Message(Messages._7201, m.FullName, "property");
						return JsExpression.Null;
				}
			}
			else if (m is IEvent) {
				var evt = (IEvent)m;
				var sem = metadataImporter.GetEventSemantics(evt);
				if (sem.Type != EventScriptSemantics.ImplType.AddAndRemoveMethods) {
					errorReporter.Message(Messages._7201, m.FullName, "event");
					return JsExpression.Null;
				}
				if (sem.AddMethod.Type != MethodScriptSemantics.ImplType.NormalMethod && sem.AddMethod.Type != MethodScriptSemantics.ImplType.StaticMethodWithThisAsFirstArgument && sem.AddMethod.Type != MethodScriptSemantics.ImplType.InlineCode) {
					errorReporter.Message(Messages._7202, m.FullName, "event", "add accessor");
					return JsExpression.Null;
				}
				if (sem.RemoveMethod.Type != MethodScriptSemantics.ImplType.NormalMethod && sem.RemoveMethod.Type != MethodScriptSemantics.ImplType.StaticMethodWithThisAsFirstArgument && sem.RemoveMethod.Type != MethodScriptSemantics.ImplType.InlineCode) {
					errorReporter.Message(Messages._7202, m.FullName, "event", "remove accessor");
					return JsExpression.Null;
				}

				properties.Add(new JsObjectLiteralProperty("type", JsExpression.Number((int)MemberTypes.Event)));
				properties.Add(new JsObjectLiteralProperty("adder", ConstructMemberInfo(evt.AddAccessor, compilation, metadataImporter, namer, runtimeLibrary, errorReporter, instantiateType, includeDeclaringType, sem.AddMethod)));
				properties.Add(new JsObjectLiteralProperty("remover", ConstructMemberInfo(evt.RemoveAccessor, compilation, metadataImporter, namer, runtimeLibrary, errorReporter, instantiateType, includeDeclaringType, sem.RemoveMethod)));
			}
			else {
				throw new ArgumentException("Invalid member " + m);
			}

			return JsExpression.ObjectLiteral(properties);
		}
		private static JsExpression ConstructConstructorInfo(IMethod constructor, ICompilation compilation, IMetadataImporter metadataImporter, INamer namer, IRuntimeLibrary runtimeLibrary, IErrorReporter errorReporter, Func<IType, JsExpression> instantiateType, bool includeDeclaringType) {
			var properties = GetCommonMemberInfoProperties(constructor, compilation, metadataImporter, namer, runtimeLibrary, errorReporter, instantiateType, includeDeclaringType);

			var sem = metadataImporter.GetConstructorSemantics(constructor);
			if (sem.Type == ConstructorScriptSemantics.ImplType.NotUsableFromScript) {
				errorReporter.Message(Messages._7200, constructor.FullName);
				return JsExpression.Null;
			}
			properties.Add(new JsObjectLiteralProperty("type", JsExpression.Number((int)MemberTypes.Constructor)));
			properties.Add(new JsObjectLiteralProperty("params", JsExpression.ArrayLiteral(constructor.Parameters.Select(p => instantiateType(p.Type)))));
			if (sem.Type == ConstructorScriptSemantics.ImplType.NamedConstructor || sem.Type == ConstructorScriptSemantics.ImplType.StaticMethod)
				properties.Add(new JsObjectLiteralProperty("sname", JsExpression.String(sem.Name)));
			if (sem.Type == ConstructorScriptSemantics.ImplType.StaticMethod)
				properties.Add(new JsObjectLiteralProperty("sm", JsExpression.True));
			if ((sem.Type == ConstructorScriptSemantics.ImplType.UnnamedConstructor || sem.Type == ConstructorScriptSemantics.ImplType.NamedConstructor || sem.Type == ConstructorScriptSemantics.ImplType.StaticMethod) && sem.ExpandParams)
				properties.Add(new JsObjectLiteralProperty("exp", JsExpression.True));
			if (sem.Type == ConstructorScriptSemantics.ImplType.Json || sem.Type == ConstructorScriptSemantics.ImplType.InlineCode) {
				var usedNames = new HashSet<string>();
				var parameters = new List<IVariable>();
				var variables = new Dictionary<IVariable, VariableData>();
				IList<ResolveResult> constructorParameters = null;
				IList<ResolveResult> initializerStatements = null;
				if (sem.Type == ConstructorScriptSemantics.ImplType.Json && constructor.DeclaringType.Kind == TypeKind.Anonymous) {
					initializerStatements = new List<ResolveResult>();
					foreach (var p in constructor.DeclaringType.GetProperties()) {
						string paramName = MakeCamelCase(p.Name);
						string name = namer.GetVariableName(paramName, usedNames);
						usedNames.Add(name);
						var variable = new SimpleVariable(p.ReturnType, paramName, DomRegion.Empty);
						parameters.Add(variable);
						variables.Add(variable, new VariableData(name, null, false));
						initializerStatements.Add(new OperatorResolveResult(p.ReturnType, ExpressionType.Assign, new MemberResolveResult(new InitializedObjectResolveResult(constructor.DeclaringType), p), new LocalResolveResult(variable)));
					}
				}
				else {
					constructorParameters = new List<ResolveResult>();
					foreach (var p in constructor.Parameters) {
						string name = namer.GetVariableName(p.Name, usedNames);
						usedNames.Add(name);
						var variable = new SimpleVariable(p.Type, p.Name, DomRegion.Empty);
						parameters.Add(variable);
						variables.Add(variable, new VariableData(name, null, false));
						constructorParameters.Add(new LocalResolveResult(variable));
					}
				}
				var compileResult = CompileConstructorInvocation(constructor, initializerStatements, constructor.DeclaringTypeDefinition, constructor, constructorParameters, compilation, metadataImporter, namer, runtimeLibrary, errorReporter, variables, usedNames);
				var definition = JsExpression.FunctionDefinition(parameters.Select(p => variables[p].Name), JsStatement.Block(compileResult.AdditionalStatements.Concat(new[] { JsStatement.Return(compileResult.Expression) })));
				properties.Add(new JsObjectLiteralProperty("def", definition));
			}
			return JsExpression.ObjectLiteral(properties);
		}
		private static ExpressionCompileResult Compile(ResolveResult rr, ITypeDefinition currentType, IMethod currentMethod, ICompilation compilation, IMetadataImporter metadataImporter, INamer namer, IRuntimeLibrary runtimeLibrary, IErrorReporter errorReporter, bool returnValueIsImportant, Dictionary<IVariable, VariableData> variables, ISet<string> usedVariableNames) {
			variables = variables ?? new Dictionary<IVariable, VariableData>();
			usedVariableNames = usedVariableNames ?? new HashSet<string>();
			return new ExpressionCompiler(compilation,
			                              metadataImporter,
			                              namer,
			                              runtimeLibrary,
			                              errorReporter,
			                              variables,
			                              new Dictionary<LambdaResolveResult, NestedFunctionData>(),
			                              t => {
			                                  string name = namer.GetVariableName(null, usedVariableNames);
			                                  IVariable variable = new SimpleVariable(t, "temporary", DomRegion.Empty);
			                                  variables[variable] = new VariableData(name, null, false);
			                                  usedVariableNames.Add(name);
			                                  return variable;
			                              },
			                              _ => { throw new Exception("Cannot compile nested functions here"); },
			                              null,
			                              new NestedFunctionContext(EmptyList<IVariable>.Instance),
			                              null,
			                              currentMethod,
			                              currentType
			                             ).Compile(rr, returnValueIsImportant);
		}
Exemple #10
0
            public static IList <JsStatement> Process(IMetadataImporter metadataImporter, INamer namer, ICompilation compilation, IList <JsStatement> statements)
            {
                var usedSymbols = UsedSymbolsGatherer.Analyze(statements);
                var importer    = new ImportVisitor(metadataImporter, namer, compilation.MainAssembly, usedSymbols);
                var body        = statements.Select(s => importer.VisitStatement(s, null)).ToList();

                if (MetadataUtils.IsAsyncModule(compilation.MainAssembly))
                {
                    body.Insert(0, new JsVariableDeclarationStatement("exports", JsExpression.ObjectLiteral()));
                    body.Add(new JsReturnStatement(JsExpression.Identifier("exports")));

                    var pairs = new[] { new KeyValuePair <string, string>("mscorlib", namer.GetVariableName("_", usedSymbols)) }.Concat(importer._moduleAliases.OrderBy(x => x.Key)).ToList();

                    body = new List <JsStatement> {
                        new JsExpressionStatement(
                            JsExpression.Invocation(
                                JsExpression.Identifier("define"),
                                JsExpression.ArrayLiteral(pairs.Select(p => JsExpression.String(p.Key))),
                                JsExpression.FunctionDefinition(
                                    pairs.Select(p => p.Value),
                                    new JsBlockStatement(body)
                                    )
                                )
                            )
                    };
                }
                else if (importer._moduleAliases.Count > 0)
                {
                    // If we require any module, we require mscorlib. This should work even if we are a leaf module that doesn't include any other module because our parent script will do the mscorlib require for us.
                    body.InsertRange(0, new[] { (JsStatement) new JsExpressionStatement(JsExpression.Invocation(JsExpression.Identifier("require"), JsExpression.String("mscorlib"))) }
                                     .Concat(importer._moduleAliases.OrderBy(x => x.Key)
                                             .Select(x => new JsVariableDeclarationStatement(
                                                         x.Value,
                                                         JsExpression.Invocation(
                                                             JsExpression.Identifier("require"),
                                                             JsExpression.String(x.Key))))
                                             .ToList()));
                }
                else
                {
                    body = new List <JsStatement> {
                        new JsExpressionStatement(JsExpression.Invocation(JsExpression.FunctionDefinition(new string[0], new JsBlockStatement(body))))
                    };
                }

                return(body);
            }
Exemple #11
0
            public static IList <JsStatement> Process(IMetadataImporter metadataImporter, INamer namer, IAttributeStore attributeStore, ICompilation compilation, IList <JsStatement> statements)
            {
                var locals          = LocalVariableGatherer.Analyze(statements);
                var globals         = ImplicitGlobalsGatherer.Analyze(statements, locals, reportGlobalsAsUsedInAllParentScopes: false);
                var introducedNames = IntroducedNamesGatherer.Analyze(statements, metadataImporter, attributeStore, compilation.MainAssembly);
                var renameMap       = RenameMapBuilder.BuildMap(statements, locals, globals, introducedNames, namer);

                var usedSymbols = new HashSet <string>();

                foreach (var sym in         locals.Values.SelectMany(v => v)                            // Declared locals.
                         .Concat(globals.Values.SelectMany(v => v))                                     // Implicitly declared globals.
                         .Concat(renameMap.Values.SelectMany(v => v.Values))                            // Locals created during preparing rename.
                         .Concat(introducedNames.Values.SelectMany(v => v))                             // All global types used.
                         )
                {
                    usedSymbols.Add(sym);
                }

                statements = IdentifierRenamer.Process(statements, renameMap).ToList();

                bool isModule = MetadataUtils.GetModuleName(compilation.MainAssembly, attributeStore) != null || MetadataUtils.IsAsyncModule(compilation.MainAssembly, attributeStore);
                var  importer = new ImportVisitor(metadataImporter, namer, attributeStore, compilation.MainAssembly, usedSymbols, JsExpression.Identifier(isModule ? "exports" : "$asm"));

                var body = (!isModule ? new[] { JsStatement.Var("$asm", JsExpression.ObjectLiteral()) } : new JsStatement[0]).Concat(statements.Select(s => importer.VisitStatement(s, null))).ToList();
                var moduleDependencies = importer._moduleAliases.Concat(MetadataUtils.GetAdditionalDependencies(compilation.MainAssembly, attributeStore));

                if (MetadataUtils.IsAsyncModule(compilation.MainAssembly, attributeStore))
                {
                    body.InsertRange(0, new[] { JsStatement.UseStrict, JsStatement.Var("exports", JsExpression.ObjectLiteral()) });
                    body.Add(JsStatement.Return(JsExpression.Identifier("exports")));

                    var pairs = new[] { new KeyValuePair <string, string>("mscorlib", namer.GetVariableName("_", usedSymbols)) }
                    .Concat(moduleDependencies.OrderBy(x => x.Key))
                    .ToList();

                    body = new List <JsStatement> {
                        JsExpression.Invocation(
                            JsExpression.Identifier("define"),
                            JsExpression.ArrayLiteral(pairs.Select(p => JsExpression.String(p.Key))),
                            JsExpression.FunctionDefinition(
                                pairs.Select(p => p.Value),
                                JsStatement.Block(body)
                                )
                            )
                    };
                }
                else if (moduleDependencies.Any())
                {
                    // If we require any module, we require mscorlib. This should work even if we are a leaf module that doesn't include any other module because our parent script will do the mscorlib require for us.
                    body.InsertRange(0, new[] { JsStatement.UseStrict, JsExpression.Invocation(JsExpression.Identifier("require"), JsExpression.String("mscorlib")) }
                                     .Concat(moduleDependencies
                                             .OrderBy(x => x.Key).OrderBy(x => x.Key)
                                             .Select(x => JsStatement.Var(
                                                         x.Value,
                                                         JsExpression.Invocation(
                                                             JsExpression.Identifier("require"),
                                                             JsExpression.String(x.Key))))
                                             .ToList()));
                }
                else
                {
                    body.Insert(0, JsStatement.UseStrict);
                    body = new List <JsStatement> {
                        JsExpression.Invocation(JsExpression.FunctionDefinition(new string[0], JsStatement.Block(body)))
                    };
                }

                return(body);
            }
Exemple #12
0
            private string FindNewName(string name, JsDeclarationScope scope)
            {
                var usedNames = _usedNames[scope];

                return(_namer.GetVariableName(name, usedNames));
            }