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)); }
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); }
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); }
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); }
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); }
private string FindNewName(string name, JsDeclarationScope scope) { var usedNames = _usedNames[scope]; return(_namer.GetVariableName(name, usedNames)); }