private JsExpression GenerateStructCloneMethod(ITypeDefinition type, string typevarName, bool hasCreateInstance) { var stmts = new List <JsStatement>() { JsStatement.Var("r", hasCreateInstance ? (JsExpression)JsExpression.Invocation(JsExpression.Member(JsExpression.Identifier(typevarName), "createInstance")) : JsExpression.New(JsExpression.Identifier(typevarName))) }; var o = JsExpression.Identifier("o"); var r = JsExpression.Identifier("r"); foreach (var f in type.Fields.Where(f => !f.IsStatic)) { var sem = _metadataImporter.GetFieldSemantics(f); if (sem.Type == FieldScriptSemantics.ImplType.Field) { var def = f.ReturnType.GetDefinition(); JsExpression value = JsExpression.Member(o, sem.Name); if (def != null && def.Kind == TypeKind.Struct && _metadataImporter.GetTypeSemantics(def).Type == TypeScriptSemantics.ImplType.MutableValueType) { value = _runtimeLibrary.CloneValueType(value, f.ReturnType, new DefaultRuntimeContext(type, _metadataImporter, _errorReporter, _namer)); } stmts.Add(JsExpression.Assign(JsExpression.Member(r, sem.Name), value)); } } foreach (var p in type.Properties.Where(p => !p.IsStatic)) { var sem = _metadataImporter.GetPropertySemantics(p); if ((sem.Type == PropertyScriptSemantics.ImplType.GetAndSetMethods && MetadataUtils.IsAutoProperty(p) == true) || sem.Type == PropertyScriptSemantics.ImplType.Field) { var def = p.ReturnType.GetDefinition(); var fieldName = sem.Type == PropertyScriptSemantics.ImplType.GetAndSetMethods ? _metadataImporter.GetAutoPropertyBackingFieldName(p) : sem.FieldName; JsExpression value = JsExpression.Member(o, fieldName); if (def != null && def.Kind == TypeKind.Struct && _metadataImporter.GetTypeSemantics(def).Type == TypeScriptSemantics.ImplType.MutableValueType) { value = _runtimeLibrary.CloneValueType(value, p.ReturnType, new DefaultRuntimeContext(type, _metadataImporter, _errorReporter, _namer)); } stmts.Add(JsExpression.Assign(JsExpression.Member(r, fieldName), value)); } } foreach (var e in type.Events.Where(e => !e.IsStatic && MetadataUtils.IsAutoEvent(e) == true)) { var sem = _metadataImporter.GetEventSemantics(e); if (sem.Type == EventScriptSemantics.ImplType.AddAndRemoveMethods) { var def = e.ReturnType.GetDefinition(); var fieldName = _metadataImporter.GetAutoEventBackingFieldName(e); JsExpression value = JsExpression.Member(o, fieldName); if (def != null && def.Kind == TypeKind.Struct && _metadataImporter.GetTypeSemantics(def).Type == TypeScriptSemantics.ImplType.MutableValueType) { value = _runtimeLibrary.CloneValueType(value, e.ReturnType, new DefaultRuntimeContext(type, _metadataImporter, _errorReporter, _namer)); } stmts.Add(JsExpression.Assign(JsExpression.Member(r, fieldName), value)); } } stmts.Add(JsStatement.Return(r)); return(JsExpression.FunctionDefinition(new[] { "o" }, JsStatement.Block(stmts))); }
public override void VisitEventDeclaration(EventDeclaration eventDeclaration) { foreach (var singleEvt in eventDeclaration.Variables) { var resolveResult = _resolver.Resolve(singleEvt); if (!(resolveResult is MemberResolveResult)) { _errorReporter.Region = eventDeclaration.GetRegion(); _errorReporter.InternalError("Event declaration " + singleEvt.Name + " does not resolve to a member."); return; } var evt = ((MemberResolveResult)resolveResult).Member as IEvent; if (evt == null) { _errorReporter.Region = eventDeclaration.GetRegion(); _errorReporter.InternalError("Event declaration " + singleEvt.Name + " does not resolve to an event (resolves to " + resolveResult.ToString() + ")"); return; } var jsClass = GetJsClass(evt.DeclaringTypeDefinition); if (jsClass == null) { return; } var impl = _metadataImporter.GetEventSemantics(evt); switch (impl.Type) { case EventScriptSemantics.ImplType.AddAndRemoveMethods: { if (evt.IsAbstract) { if (impl.AddMethod.GeneratedMethodName != null) { AddCompiledMethodToType(jsClass, evt.AddAccessor, impl.AddMethod, new JsMethod(evt.AddAccessor, impl.AddMethod.GeneratedMethodName, null, null)); } if (impl.RemoveMethod.GeneratedMethodName != null) { AddCompiledMethodToType(jsClass, evt.RemoveAccessor, impl.RemoveMethod, new JsMethod(evt.RemoveAccessor, impl.RemoveMethod.GeneratedMethodName, null, null)); } } else { var fieldName = _metadataImporter.GetAutoEventBackingFieldName(evt); if (_metadataImporter.ShouldGenerateAutoEventBackingField(evt)) { if (singleEvt.Initializer.IsNull) { AddDefaultFieldInitializerToType(jsClass, fieldName, evt, evt.IsStatic); } else { CompileAndAddFieldInitializerToType(jsClass, fieldName, evt, singleEvt.Initializer, evt.IsStatic); } } CompileAndAddAutoEventMethodsToType(jsClass, eventDeclaration, evt, impl, fieldName); } break; } case EventScriptSemantics.ImplType.NotUsableFromScript: { break; } default: { throw new InvalidOperationException("Invalid event implementation type"); } } } }
public virtual string GetAutoEventBackingFieldName(IEvent evt) { return(_prev.GetAutoEventBackingFieldName(evt)); }