Exemplo n.º 1
0
        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));
            }
        }
Exemplo n.º 2
0
        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));
            }
        }
Exemplo n.º 3
0
        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));
            }
        }