protected virtual void EmitClassHeader() { var beforeDefineMethods = this.GetBeforeDefineMethods(); if (beforeDefineMethods.Any()) { foreach (var method in beforeDefineMethods) { this.WriteNewLine(); this.Write(method); } this.WriteNewLine(); } var topDefineMethods = this.GetTopDefineMethods(); if (topDefineMethods.Any()) { foreach (var method in topDefineMethods) { //this.Emitter.EmitterOutput.TopOutput.Append('\n'); this.Emitter.EmitterOutput.TopOutput.Append(method); } //this.Emitter.EmitterOutput.TopOutput.Append('\n'); } var typeDef = this.Emitter.GetTypeDefinition(); string name = this.Emitter.Validator.GetCustomTypeName(typeDef, this.Emitter); this.IsGeneric = typeDef.GenericParameters.Count > 0; if (name.IsEmpty()) { name = BridgeTypes.DefinitionToJsName(this.TypeInfo.Type, this.Emitter); } this.Write(Bridge.Translator.Emitter.ROOT + ".define"); this.WriteOpenParentheses(); this.Write("'" + name, "'"); this.StartPosition = this.Emitter.Output.Length; this.Write(", "); if (this.IsGeneric) { this.WriteFunction(); this.WriteOpenParentheses(); foreach (var p in typeDef.GenericParameters) { this.EnsureComma(false); this.Write(p.Name); this.Emitter.Comma = true; } this.Emitter.Comma = false; this.WriteCloseParentheses(); this.Write(" { return "); } this.BeginBlock(); string extend = this.Emitter.GetTypeHierarchy(); if (extend.IsNotEmpty() && !this.TypeInfo.IsEnum) { var bridgeType = this.Emitter.BridgeTypes.Get(this.Emitter.TypeInfo); if (this.TypeInfo.InstanceMethods.Any(m => m.Value.Any(subm => this.Emitter.GetEntityName(subm) == "inherits")) || this.TypeInfo.InstanceConfig.Fields.Any(m => m.GetName(this.Emitter) == "inherits")) { this.Write("$"); } this.Write("inherits"); this.WriteColon(); if (Helpers.IsTypeArgInSubclass(bridgeType.TypeDefinition, bridgeType.TypeDefinition, this.Emitter, false)) { this.WriteFunction(); this.WriteOpenCloseParentheses(true); this.WriteOpenBrace(true); this.WriteReturn(true); this.Write(extend); this.WriteSemiColon(); this.WriteCloseBrace(true); } else { this.Write(extend); } this.Emitter.Comma = true; } if (this.TypeInfo.Module != null) { this.WriteScope(); } }
protected virtual void EmitCtorForInstantiableClass() { var baseType = this.Emitter.GetBaseTypeDefinition(); var typeDef = this.Emitter.GetTypeDefinition(); var isObjectLiteral = this.Emitter.Validator.IsObjectLiteral(typeDef); var isPlainMode = this.Emitter.Validator.GetObjectCreateMode(typeDef) == 0; var ctorWrappers = isObjectLiteral ? new string[0] : this.EmitInitMembers().ToArray(); if (!this.TypeInfo.HasRealInstantiable(this.Emitter) && ctorWrappers.Length == 0 || isObjectLiteral && isPlainMode) { if (this.ctorHeader) { this.WriteNewLine(); this.EndBlock(); } return; } bool forceDefCtor = isObjectLiteral && this.Emitter.Validator.GetObjectCreateMode(typeDef) == 1 && this.TypeInfo.Ctors.Count == 0; if (typeDef.IsValueType || forceDefCtor || (this.TypeInfo.Ctors.Count == 0 && ctorWrappers.Length > 0)) { this.TypeInfo.Ctors.Add(new ConstructorDeclaration { Modifiers = Modifiers.Public, Body = new BlockStatement() }); } if (!this.ctorHeader && this.TypeInfo.Ctors.Count > 0) { this.EnsureComma(); this.ctorHeader = true; this.Write(JS.Fields.CTORS); this.WriteColon(); this.BeginBlock(); } this.Emitter.InConstructor = true; foreach (var ctor in this.TypeInfo.Ctors) { this.EnsureComma(); this.ResetLocals(); var prevMap = this.BuildLocalsMap(); var prevNamesMap = this.BuildLocalsNamesMap(); this.AddLocals(ctor.Parameters, ctor.Body); var ctorName = JS.Funcs.CONSTRUCTOR; if (this.TypeInfo.Ctors.Count > 1 && ctor.Parameters.Count > 0) { var overloads = OverloadsCollection.Create(this.Emitter, ctor); ctorName = overloads.GetOverloadName(); } XmlToJsDoc.EmitComment(this, ctor); this.Write(ctorName); this.WriteColon(); this.WriteFunction(); int pos = this.Emitter.Output.Length; this.EmitMethodParameters(ctor.Parameters, null, ctor); var ctorParams = this.Emitter.Output.ToString().Substring(pos); this.WriteSpace(); this.BeginBlock(); var len = this.Emitter.Output.Length; var requireNewLine = false; var noThisInvocation = ctor.Initializer == null || ctor.Initializer.IsNull || ctor.Initializer.ConstructorInitializerType == ConstructorInitializerType.Base; IWriterInfo oldWriter = null; if (ctorWrappers.Length > 0 && noThisInvocation) { oldWriter = this.SaveWriter(); this.NewWriter(); } this.ConvertParamsToReferences(ctor.Parameters); if (len != this.Emitter.Output.Length) { requireNewLine = true; } if (isObjectLiteral) { if (requireNewLine) { this.WriteNewLine(); } this.Write("var " + JS.Vars.D_THIS + " = "); var isBaseObjectLiteral = baseType != null && this.Emitter.Validator.IsObjectLiteral(baseType); if (isBaseObjectLiteral && baseType != null && (!this.Emitter.Validator.IsExternalType(baseType) || this.Emitter.Validator.IsBridgeClass(baseType)) || (ctor.Initializer != null && ctor.Initializer.ConstructorInitializerType == ConstructorInitializerType.This)) { this.EmitBaseConstructor(ctor, ctorName, true); } else if (isBaseObjectLiteral && baseType != null && ctor.Initializer != null && ctor.Initializer.ConstructorInitializerType == ConstructorInitializerType.Base) { this.EmitExternalBaseCtor(ctor, ref requireNewLine); } else { this.Write("{};"); } this.WriteNewLine(); string name = this.Emitter.Validator.GetCustomTypeName(typeDef, this.Emitter, false); if (name.IsEmpty()) { name = BridgeTypes.DefinitionToJsName(this.TypeInfo.Type, this.Emitter); } this.Write(JS.Vars.D_THIS + "." + JS.Funcs.GET_TYPE + " = function () { return " + name + "; };"); this.WriteNewLine(); this.Write("(function ()"); this.BeginBlock(); requireNewLine = false; } if (noThisInvocation) { if (requireNewLine) { this.WriteNewLine(); } if (isObjectLiteral) { var fieldBlock = new FieldBlock(this.Emitter, this.TypeInfo, false, false, true); fieldBlock.Emit(); var properties = this.TypeInfo.InstanceProperties; var names = new List <string>(properties.Keys); foreach (var name in names) { var props = properties[name]; foreach (var prop in props) { var p = prop as PropertyDeclaration; if (p != null) { if (p.Getter.Body.IsNull && p.Setter.Body.IsNull) { continue; } this.Write(JS.Types.Object.DEFINEPROPERTY); this.WriteOpenParentheses(); this.Write("this, "); this.WriteScript(OverloadsCollection.Create(this.Emitter, p).GetOverloadName()); this.WriteComma(); this.Emitter.Comma = false; this.BeginBlock(); var memberResult = this.Emitter.Resolver.ResolveNode(p, this.Emitter) as MemberResolveResult; var block = new VisitorPropertyBlock(this.Emitter, p); block.EmitPropertyMethod(p, p.Getter, ((IProperty)memberResult.Member).Getter, false, true); block.EmitPropertyMethod(p, p.Setter, ((IProperty)memberResult.Member).Setter, true, true); this.EnsureComma(true); this.Write(JS.Fields.ENUMERABLE + ": true"); this.WriteNewLine(); this.EndBlock(); this.WriteCloseParentheses(); this.Write(";"); this.WriteNewLine(); } } } } else { this.Write("this." + JS.Funcs.INITIALIZE + "();"); requireNewLine = true; } } if (!isObjectLiteral) { if (baseType != null && (!this.Emitter.Validator.IsExternalType(baseType) || this.Emitter.Validator.IsBridgeClass(baseType)) || (ctor.Initializer != null && ctor.Initializer.ConstructorInitializerType == ConstructorInitializerType.This)) { if (requireNewLine) { this.WriteNewLine(); requireNewLine = false; } this.EmitBaseConstructor(ctor, ctorName, false); } else if (baseType != null && ctor.Initializer != null && ctor.Initializer.ConstructorInitializerType == ConstructorInitializerType.Base) { this.EmitExternalBaseCtor(ctor, ref requireNewLine); } } var script = this.Emitter.GetScript(ctor); if (script == null) { if (ctor.Body.HasChildren) { var beginPosition = this.Emitter.Output.Length; if (requireNewLine) { this.WriteNewLine(); } ctor.Body.AcceptChildren(this.Emitter); if (!this.Emitter.IsAsync) { this.EmitTempVars(beginPosition, true); } } else if (requireNewLine) { this.WriteNewLine(); } } else { if (requireNewLine) { this.WriteNewLine(); } this.WriteLines(script); } if (oldWriter != null) { this.WrapBody(oldWriter, ctorWrappers, ctorParams); } if (isObjectLiteral) { if (requireNewLine) { this.WriteNewLine(); } this.EndBlock(); this.Write(")." + JS.Funcs.CALL + "(" + JS.Vars.D_THIS + ");"); this.WriteNewLine(); this.Write("return " + JS.Vars.D_THIS + ";"); this.WriteNewLine(); } this.EndBlock(); this.Emitter.Comma = true; this.ClearLocalsMap(prevMap); this.ClearLocalsNamesMap(prevNamesMap); } this.Emitter.InConstructor = false; if (this.ctorHeader) { this.WriteNewLine(); this.EndBlock(); } }
protected virtual void EmitClassHeader() { this.WriteTopInitMethods(); var typeDef = this.Emitter.GetTypeDefinition(); string name = this.Emitter.Validator.GetCustomTypeName(typeDef, this.Emitter); this.IsGeneric = typeDef.GenericParameters.Count > 0 && !Helpers.IsIgnoreGeneric(this.TypeInfo.Type, this.Emitter); if (name.IsEmpty()) { name = BridgeTypes.DefinitionToJsName(this.TypeInfo.Type, this.Emitter); } if (typeDef.IsInterface && typeDef.HasGenericParameters) { this.Write(JS.Funcs.BRIDGE_DEFINEI); } else { this.Write(JS.Funcs.BRIDGE_DEFINE); } this.WriteOpenParentheses(); this.Write("'" + name, "'"); this.StartPosition = this.Emitter.Output.Length; this.Write(", "); if (this.IsGeneric) { this.WriteFunction(); this.WriteOpenParentheses(); foreach (var p in typeDef.GenericParameters) { this.EnsureComma(false); this.Write(p.Name); this.Emitter.Comma = true; } this.Emitter.Comma = false; this.WriteCloseParentheses(); this.Write(" { return "); } this.BeginBlock(); string extend = this.Emitter.GetTypeHierarchy(); if (extend.IsNotEmpty() && !this.TypeInfo.IsEnum) { var bridgeType = this.Emitter.BridgeTypes.Get(this.Emitter.TypeInfo); if (this.TypeInfo.InstanceMethods.Any(m => m.Value.Any(subm => this.Emitter.GetEntityName(subm) == JS.Fields.INHERITS)) || this.TypeInfo.InstanceConfig.Fields.Any(m => m.GetName(this.Emitter) == JS.Fields.INHERITS)) { this.Write(JS.Vars.D); } this.Write(JS.Fields.INHERITS); this.WriteColon(); if (Helpers.IsTypeArgInSubclass(bridgeType.TypeDefinition, bridgeType.TypeDefinition, this.Emitter, false)) { this.WriteFunction(); this.WriteOpenCloseParentheses(true); this.WriteOpenBrace(true); this.WriteReturn(true); this.Write(extend); this.WriteSemiColon(); this.WriteCloseBrace(true); } else { this.Write(extend); } this.Emitter.Comma = true; } this.WriteKind(); if (this.TypeInfo.Module != null) { this.WriteScope(); } this.WriteVariance(); }
private void EmitClassHeader() { var beforeDefineMethods = this.GetBeforeDefineMethods(); if (beforeDefineMethods.Any()) { foreach (var method in beforeDefineMethods) { this.WriteNewLine(); this.Write(method); } this.WriteNewLine(); } var topDefineMethods = this.GetTopDefineMethods(); foreach (var method in topDefineMethods) { this.Emitter.EmitterOutput.TopOutput.Append(method); } string typeName, namespaceName; var typeDef = this.Emitter.GetTypeDefinition(); string name = this.Emitter.Validator.GetCustomTypeName(typeDef, this.Emitter); if (name.IsNotEmpty()) { int pos = name.LastIndexOf('.'); if (pos != -1) { typeName = name.Substring(pos + 1); namespaceName = name.Substring(0, pos); } else { typeName = name; namespaceName = null; } } else { name = BridgeTypes.DefinitionToJsName(this.TypeInfo.Type, this.Emitter); namespaceName = this.TypeInfo.Namespace; if (!string.IsNullOrEmpty(namespaceName)) { if (!name.StartsWith(namespaceName)) { throw new System.Exception(); } typeName = name.Substring(namespaceName.Length + 1); } else { typeName = name; } } TransformCtx.NamespaceNames.Add(this.TypeInfo, namespaceName); string methodName; if (typeDef.IsEnum) { methodName = "enum"; } else if (typeDef.IsValueType) { methodName = "struct"; } else if (typeDef.IsInterface) { methodName = "interface"; } else { methodName = "class"; } this.Indent(); this.Write("namespace.", methodName); this.WriteOpenParentheses(); this.Write("\"", typeName, "\""); this.WriteComma(); this.WriteFunction(); this.WriteOpenParentheses(); this.WriteCloseParentheses(); this.BeginFunctionBlock(); this.IsGeneric = typeDef.GenericParameters.Count > 0; if (this.IsGeneric) { this.WriteReturn(true); this.WriteFunction(); this.WriteOpenParentheses(); foreach (var p in typeDef.GenericParameters) { this.EnsureComma(false); this.Write(p.Name); this.Emitter.Comma = true; } this.Emitter.Comma = false; this.WriteCloseParentheses(); this.BeginFunctionBlock(); } if (this.TypeInfo.TypeDeclaration.ClassType != ClassType.Interface) { this.EmitStaticBlock(false); this.EmitInstantiableBlock(false); this.Emitter.Comma = false; if (TransformCtx.CurClassMethodNames.Count > 0) { WriteMethodNames(TransformCtx.CurClassMethodNames); } methodsPosIndex_ = this.Emitter.Output.Length; if (methods_.Length > 0) { this.Write(""); this.Write(methods_); this.WriteNewLine(); } } this.WriteReturn(true); this.BeginBlock(); fieldAreaStartPostion_ = this.Emitter.Output.Length; string extend = this.Emitter.GetTypeHierarchy(); if (extend.IsNotEmpty() && !this.TypeInfo.IsEnum) { string inherits = "inherits".Ident(); this.Write(inherits); this.WriteEqualsSign(); var bridgeType = this.Emitter.BridgeTypes.Get(this.Emitter.TypeInfo); if (Helpers.IsTypeArgInSubclass(bridgeType.TypeDefinition, bridgeType.TypeDefinition, this.Emitter, false)) { this.WriteFunction(); this.WriteOpenCloseParentheses(true); this.WriteReturn(true); this.Write(extend); this.WriteSemiColon(); this.WriteSpace(); this.WriteEnd(); } else { this.Write(extend); } this.Emitter.Comma = true; } if (this.TypeInfo.Module != null) { this.WriteScope(); } }