private void HandleConstructorDeclaration(ConstructorDeclaration constructorDeclaration) { var resolveResult = _resolver.Resolve(constructorDeclaration); if (!(resolveResult is MemberResolveResult)) { _errorReporter.Region = constructorDeclaration.GetRegion(); _errorReporter.InternalError("Method declaration " + constructorDeclaration.Name + " does not resolve to a member."); return; } var method = ((MemberResolveResult)resolveResult).Member as IMethod; if (method == null) { _errorReporter.Region = constructorDeclaration.GetRegion(); _errorReporter.InternalError("Method declaration " + constructorDeclaration.Name + " does not resolve to a method (resolves to " + resolveResult.ToString() + ")"); return; } var jsClass = GetJsClass(method.DeclaringTypeDefinition); if (jsClass == null) { return; } if (method.IsStatic) { jsClass.StaticInitStatements.AddRange(CompileMethod(constructorDeclaration, constructorDeclaration.Body, method, MethodScriptSemantics.NormalMethod("X")).Body.Statements); } else { MaybeCompileAndAddConstructorToType(jsClass, constructorDeclaration, method, _metadataImporter.GetConstructorSemantics(method)); } }
private void HandleConstructorDeclaration(ConstructorDeclaration constructorDeclaration) { var resolveResult = _resolver.Resolve(constructorDeclaration); if (!(resolveResult is MemberResolveResult)) { _errorReporter.Region = constructorDeclaration.GetRegion(); _errorReporter.InternalError("Method declaration " + constructorDeclaration.Name + " does not resolve to a member."); return; } var method = ((MemberResolveResult)resolveResult).Member as IMethod; if (method == null) { _errorReporter.Region = constructorDeclaration.GetRegion(); _errorReporter.InternalError("Method declaration " + constructorDeclaration.Name + " does not resolve to a method (resolves to " + resolveResult.ToString() + ")"); return; } var jsClass = GetJsClass(method.DeclaringTypeDefinition); if (jsClass == null) return; if (method.IsStatic) { jsClass.StaticInitStatements.AddRange(CompileMethod(constructorDeclaration, constructorDeclaration.Body, method, MethodScriptSemantics.NormalMethod("X")).Body.Statements); } else { MaybeCompileAndAddConstructorToType(jsClass, constructorDeclaration, method, _metadataImporter.GetConstructorSemantics(method)); } }
public JsFunctionDefinitionExpression CompileConstructor(ConstructorDeclaration ctor, IMethod constructor, List <JsStatement> instanceInitStatements, ConstructorScriptSemantics impl) { var region = _errorReporter.Region = ctor != null?ctor.GetRegion() : constructor.DeclaringTypeDefinition.Region; try { CreateCompilationContext(ctor, constructor, constructor.DeclaringTypeDefinition, (impl.Type == ConstructorScriptSemantics.ImplType.StaticMethod ? _namer.ThisAlias : null)); IList <JsStatement> body = new List <JsStatement>(); body.AddRange(PrepareParameters(constructor.Parameters, variables, expandParams: impl.ExpandParams, staticMethodWithThisAsFirstArgument: false)); if (impl.Type == ConstructorScriptSemantics.ImplType.StaticMethod) { if (ctor != null && !ctor.Initializer.IsNull) { body.AddRange(_statementCompiler.CompileConstructorInitializer(ctor.Initializer, true)); } else { body.AddRange(_statementCompiler.CompileImplicitBaseConstructorCall(constructor.DeclaringTypeDefinition, true)); } } if (ctor == null || ctor.Initializer.IsNull || ctor.Initializer.ConstructorInitializerType != ConstructorInitializerType.This) { if (impl.Type == ConstructorScriptSemantics.ImplType.StaticMethod) { // The compiler one step up has created the statements as "this.a = b;", but we need to replace that with "$this.a = b;" (or whatever name the this alias has). var replacer = new ThisReplacer(JsExpression.Identifier(_namer.ThisAlias)); instanceInitStatements = instanceInitStatements.Select(s => replacer.VisitStatement(s, null)).ToList(); } body.AddRange(instanceInitStatements); // Don't initialize fields when we are chaining, but do it when we 1) compile the default constructor, 2) don't have an initializer, or 3) when the initializer is not this(...). } if (impl.Type != ConstructorScriptSemantics.ImplType.StaticMethod) { if (ctor != null && !ctor.Initializer.IsNull) { body.AddRange(_statementCompiler.CompileConstructorInitializer(ctor.Initializer, false)); } else { body.AddRange(_statementCompiler.CompileImplicitBaseConstructorCall(constructor.DeclaringTypeDefinition, false)); } } if (ctor != null) { body.AddRange(_statementCompiler.Compile(ctor.Body).Statements); } if (impl.Type == ConstructorScriptSemantics.ImplType.StaticMethod) { if (body.Count == 0 || !(body[body.Count - 1] is JsReturnStatement)) { body.Add(JsStatement.Return()); } body = StaticMethodConstructorReturnPatcher.Process(body, _namer.ThisAlias).AsReadOnly(); } var compiled = JsExpression.FunctionDefinition(constructor.Parameters.Where((p, i) => i != constructor.Parameters.Count - 1 || !impl.ExpandParams).Select(p => variables[p].Name), JsStatement.Block(body)); return(_statementCompiler.StateMachineRewriteNormalMethod(compiled)); } catch (Exception ex) { _errorReporter.Region = region; _errorReporter.InternalError(ex); return(JsExpression.FunctionDefinition(new string[0], JsStatement.EmptyBlock)); } }