Exemple #1
1
 public void AddMethod(MessageContext ctxt, CST.MethodDef methodDef)
 {
     var trace = Parent.Parent;
     var name = methodDef.QualifiedMemberName(trace.Parent.Env.Global, Parent.Assembly, Type);
     if (trace.Parent.FirstOccuranceOfMethod(ctxt, name, trace))
         Methods.Add(methodDef.MethodSignature);
 }
Exemple #2
0
 public AssemblyTrace(Trace parent, CST.AssemblyDef assembly)
 {
     Parent = parent;
     Assembly = assembly;
     IncludeAssembly = false;
     TypeMap = new Map<CST.TypeName, TypeTrace>();
 }
Exemple #3
0
 private static bool IsUpToDate(CompilerEnvironment env, CST.AssemblyDef assembly, bool complain)
 {
     var annot = assembly.Annotations.OfType<CST.AssemblyFileAnnotation>().FirstOrDefault();
     if (annot == null)
         throw new InvalidOperationException("assembly is missing file annotation");
     var fn = default(string);
     var lastCompTime = AssemblyCompiler.LastCompilationTime(env, assembly.Name, out fn);
     if (lastCompTime.HasValue)
     {
         if (annot.LastWriteTime <= lastCompTime.Value)
             return true;
         else
         {
             if (complain)
                 env.Log
                     (new OutOfDateAssemblyMessage(assembly.Name, annot.CanonicalFileName, fn));
             return false;
         }
     }
     else
     {
         if (complain)
             env.Log(new AssemblyNotCompiledMessage(assembly.Name, fn));
         return false;
     }
 }
Exemple #4
0
 public TypeTrace(AssemblyTrace parent, CST.TypeDef type)
 {
     Parent = parent;
     Type = type;
     IncludeType = false;
     Methods = new Set<CST.MethodSignature>();
 }
Exemple #5
0
        public MethodCompiler(TypeDefinitionCompiler parent, JST.NameSupply outerNameSupply, CST.MethodDef methodDef, MethodCompilationMode mode)
        {
            env = parent.Env;
            this.parent = parent;
            methEnv = parent.TyconEnv.AddSelfTypeBoundArguments().AddMethod(methodDef).AddSelfMethodBoundArguments();
            messageCtxt = CST.MessageContextBuilders.Env(methEnv);
            this.mode = mode;
            this.outerNameSupply = outerNameSupply;

            var common = default(JST.NameSupply);
            switch (mode)
            {
            case MethodCompilationMode.SelfContained:
                common = outerNameSupply;
                // Will be bound by function passed to root's BindMethod
                rootId = common.GenSym();
                assemblyId = common.GenSym();
                typeDefinitionId = common.GenSym();
                break;
            case MethodCompilationMode.DirectBind:
                common = outerNameSupply.Fork();
                // Already bound
                rootId = parent.RootId;
                assemblyId = parent.AssemblyId;
                typeDefinitionId = parent.TypeDefinitionId;
                break;
            default:
                throw new ArgumentOutOfRangeException("mode");
            }

            nameSupply = common.Fork();
            simpNameSupply = common.Fork();
        }
Exemple #6
0
 public string ResolveTypeRefToSlot(CST.TypeRef typeRef)
 {
     var assemblyDef = default(CST.AssemblyDef);
     if (typeRef.QualifiedTypeName.Assembly.PrimTryResolve(env.Global, out assemblyDef))
         return AssemblyMappingFor(assemblyDef).ResolveTypeDefinitionToSlot(typeRef.QualifiedTypeName.Type);
     else
         throw new InvalidOperationException("invalid type ref");
 }
 // Collecting mode entry point
 public AssemblyCompiler(CompilerEnvironment env, CST.AssemblyDef assemblyDef)
     : this(env)
 {
     assmEnv = env.Global.Environment().AddAssembly(assemblyDef);
     assemblyTrace = null;
     NameSupply = new JST.NameSupply(Constants.Globals);
     rootId = NameSupply.GenSym();
     assemblyId = NameSupply.GenSym();
 }
Exemple #8
0
 public string ResolveFieldRefToSlot(CST.FieldRef fieldRef)
 {
     var assemblyDef = default(CST.AssemblyDef);
     var typeDef = default(CST.TypeDef);
     if (fieldRef.DefiningType.PrimTryResolve(env.Global, out assemblyDef, out typeDef))
         return TypeMappingFor(assemblyDef, typeDef).ResolveFieldToSlot(fieldRef.QualifiedMemberName);
     else
         throw new InvalidOperationException("invalid field ref");
 }
Exemple #9
0
 private TypeMapping TypeMappingFor(CST.AssemblyDef assemblyDef, CST.TypeDef typeDef)
 {
     var name = typeDef.QualifiedTypeName(env.Global, assemblyDef);
     var typeMapping = default(TypeMapping);
     if (!typeMappingCache.TryGetValue(name, out typeMapping))
     {
         typeMapping = new TypeMapping(env, assemblyDef, typeDef);
         typeMappingCache.Add(name, typeMapping);
     }
     return typeMapping;
 }
Exemple #10
0
 private AssemblyMapping AssemblyMappingFor(CST.AssemblyDef assemblyDef)
 {
     var name = assemblyDef.Name;
     var assemblyMapping = default(AssemblyMapping);
     if (!assemblyMappingCache.TryGetValue(name, out assemblyMapping))
     {
         assemblyMapping = new AssemblyMapping(env, assemblyDef);
         assemblyMappingCache.Add(name, assemblyMapping);
     }
     return assemblyMapping;
 }
Exemple #11
0
 private bool HasFullReflection(CST.AssemblyDef assemblyDef, CST.TypeDef typeDef)
 {
     var level = default(ReflectionLevel);
     env.AttributeHelper.GetValueFromType
         (assemblyDef,
          typeDef,
          env.AttributeHelper.ReflectionAttributeRef,
          env.AttributeHelper.TheReflectionLevelProperty,
          true,
          true,
          ref level);
     return level >= ReflectionLevel.Full;
 }
Exemple #12
0
        // NOTE: May be called on invalid definitions
        public override bool FieldAlwaysUsed(CST.AssemblyDef assemblyDef, CST.TypeDef typeDef, CST.FieldDef fieldDef)
        {
#if false
            if (env.AttributeHelper.FieldHasAttribute(assemblyDef, typeDef, fieldDef, env.Global.CompilerGeneratedAttributeRef, false))
                return false;
#endif
            if (env.AttributeHelper.FieldHasAttribute(assemblyDef, typeDef, fieldDef, env.AttributeHelper.IgnoreAttributeRef, true, true))
                return false;

            if (HasFullReflection(assemblyDef, typeDef))
                return true;

            var isUsed = default(bool);
            env.AttributeHelper.GetValueFromField(assemblyDef, typeDef, fieldDef, env.AttributeHelper.UsedAttributeRef, env.AttributeHelper.TheIsUsedProperty, true, false, ref isUsed);
            if (isUsed)
                return true;

            return false;
        }
        public bool CouldBeInlinableBasedOnHeaderAlone(CST.AssemblyDef assemblyDef, CST.TypeDef typeDef, CST.MethodDef methodDef)
        {
            if (methodDef.IsVirtualOrAbstract || typeDef.Style is CST.InterfaceTypeStyle)
                // No virtuals or interface methods
                return false;

            if (typeDef.Style is CST.MultiDimArrayTypeStyle)
                // Implemented by runtime
                return false;

            if (typeDef.IsAttributeType(env.Global, assemblyDef))
                // Don't inline attribute property methods since we invoke them directly when building attributes
                return false;

            var level = default(ReflectionLevel);
            env.AttributeHelper.GetValueFromType
                (assemblyDef,
                 typeDef,
                 env.AttributeHelper.ReflectionAttributeRef,
                 env.AttributeHelper.TheReflectionLevelProperty,
                 true,
                 true,
                 ref level);
            if (level >= ReflectionLevel.Full)
                // No inlining in classes needing full reflection since need to support dynamic invokes
                return false;

            // NOTE: Method may be used in a delegate, in which case it's fine to inline but we'll still
            //       need to emit the definition

            if (assemblyDef.EntryPoint != null &&
                assemblyDef.EntryPoint.QualifiedMemberName.Equals
                    (methodDef.QualifiedMemberName(env.Global, assemblyDef, typeDef)))
                // Entry points are called directly by startup code
                return false;

            return true;
        }
Exemple #14
0
 public override CST.InvalidInfo ImplementableTypeRef(MessageContext ctxt, CST.RootEnvironment rootEnv, CST.TypeRef typeRef)
 {
     var s = typeRef.Style(rootEnv);
     if (s is CST.UnmanagedPointerTypeStyle)
     {
         Log(new CST.InvalidTypeRef(ctxt, typeRef, "Unmanaged pointers are not supported"));
         return new CST.InvalidInfo(CST.MessageContextBuilders.Type(Global, typeRef));
     }
     return null;
 }
Exemple #15
0
 public override CST.InvalidInfo ImplementableInstruction(MessageContext ctxt, CST.AssemblyDef assemblyDef, CST.TypeDef typeDef, CST.MethodDef methodDef, CST.Instruction instruction)
 {
     switch (instruction.Flavor)
     {
         case CST.InstructionFlavor.Try:
             {
                 var tryi = (CST.TryInstruction)instruction;
                 if (tryi.Handlers.Any(h => h.Flavor == CST.HandlerFlavor.Filter))
                 {
                     Log
                         (new CST.InvalidInstruction
                              (ctxt, instruction, "Exception filter blocks are not supported"));
                     return new CST.InvalidInfo(CST.MessageContextBuilders.Instruction(Global, instruction));
                 }
                 break;
             }
         default:
             break;
     }
     return null;
 }
Exemple #16
0
        public override void ImplementableMemberDef(CST.AssemblyDef assemblyDef, CST.TypeDef typeDef, CST.MemberDef memberDef)
        {
            var ctxt = CST.MessageContextBuilders.Member(env.Global, assemblyDef, typeDef, memberDef);
            var s = typeDef.Style;

            var methodDef = memberDef as CST.MethodDef;
            if (methodDef == null)
                return;

            if (s is CST.DelegateTypeStyle || s is CST.MultiDimArrayTypeStyle)
                // SPECIAL CASE: Magic delegate and multi-dimensional array methods are
                //               implemented by runtime
                return;

            if (env.AttributeHelper.MethodHasAttribute
                (assemblyDef, typeDef, methodDef, env.AttributeHelper.IgnoreAttributeRef, true, true))
            {
                Log(new CST.InvalidMemberDef(ctxt, "Method is marked as '[Ignore]'"));
                methodDef.Invalid = new CST.InvalidInfo("Ignored");
            }

            try
            {
                if (!(s is CST.InterfaceTypeStyle) && methodDef.MethodStyle != CST.MethodStyle.Abstract &&
                    !env.InteropManager.IsImported(assemblyDef, typeDef, methodDef))
                {
                    switch (methodDef.CodeFlavor)
                    {
                        case CST.MethodCodeFlavor.Managed:
                        {
                            var instructions = methodDef.Instructions(Global);
                            if (instructions == null || instructions.Body.Count == 0)
                            {
                                Log(new CST.InvalidMemberDef(ctxt, "Method has no body"));
                                methodDef.Invalid = new CST.InvalidInfo("Unimplementable");
                            }
                            break;
                        }
                    case CST.MethodCodeFlavor.ManagedExtern:
                            Log(new CST.InvalidMemberDef(ctxt, "Method is marked as extern but has no import"));
                            methodDef.Invalid = new CST.InvalidInfo("Unimplementable");
                            break;
                        case CST.MethodCodeFlavor.Native:
                            Log(new CST.InvalidMemberDef(ctxt, "Method invokes native code"));
                            methodDef.Invalid = new CST.InvalidInfo("Unimplementable");
                            break;
                        case CST.MethodCodeFlavor.Runtime:
                            Log(new CST.InvalidMemberDef(ctxt, "Method is part of the CLR runtime"));
                            methodDef.Invalid = new CST.InvalidInfo("Unimplementable");
                            break;
                        case CST.MethodCodeFlavor.ForwardRef:
                            Log(new CST.InvalidMemberDef(ctxt, "Method is a forward reference"));
                            methodDef.Invalid = new CST.InvalidInfo("Unimplementable");
                            break;
                        default:
                            throw new ArgumentOutOfRangeException();
                    }
                }
                // else: no body to check
            }
            catch (DefinitionException)
            {
                Log(new CST.InvalidMemberDef(ctxt, "Method contains an interop error"));
                methodDef.Invalid = new CST.InvalidInfo("Unimplementable");
            }
        }
Exemple #17
0
 public override void ImplementableTypeDef(CST.AssemblyDef assemblyDef, CST.TypeDef typeDef)
 {
     if (env.AttributeHelper.TypeHasAttribute
         (assemblyDef, typeDef, env.AttributeHelper.IgnoreAttributeRef, true, true))
     {
         var ctxt = CST.MessageContextBuilders.Type(env.Global, assemblyDef, typeDef);
         Log(new CST.InvalidTypeDef(ctxt, "Type is marked as '[Ignore]'"));
         typeDef.Invalid = new CST.InvalidInfo("Ignored");
     }
 }
Exemple #18
0
 public override bool IgnoreMethodDefBody(CST.AssemblyDef assemblyDef, CST.TypeDef typeDef, CST.MethodDef methodDef)
 {
     return env.AttributeHelper.MethodHasAttribute(assemblyDef, typeDef, methodDef, env.AttributeHelper.InteropGeneratedAttributeRef, false, false);
 }
Exemple #19
0
        public bool IsNoInteropParameter(CST.AssemblyDef assemblyDef, CST.TypeDef typeDef, CST.MethodDef methodDef, int idx)
        {
            if (!methodDef.IsStatic && idx == 0)
            {
                // We must look for [Runtime] on the method's declaring type, since the CLR does not
                // allow custom attributes on implicit arguments

                var isRuntime = default(bool);
                attributeHelper.GetValueFromType
                    (assemblyDef,
                     typeDef,
                     attributeHelper.RuntimeAttributeRef,
                     attributeHelper.TheIsRuntimeProperty,
                     true,
                     false,
                     ref isRuntime);
                return isRuntime;
            }
            else
            {
                var isNoInterop = default(bool);
                attributeHelper.GetValueFromParameter
                    (assemblyDef,
                     typeDef,
                     methodDef,
                     idx,
                     attributeHelper.NoInteropAttributeRef,
                     attributeHelper.TheIsNoInteropProperty,
                     true,
                     false,
                     ref isNoInterop);
                return isNoInterop;
            }
        }
Exemple #20
0
 public override bool IncludeAttributes(CST.AssemblyDef assemblyDef, CST.TypeDef typeDef)
 {
     return HasFullReflection(assemblyDef, typeDef);
 }
Exemple #21
0
        public override bool PropogateExtraUsedFromType(CST.AssemblyDef assemblyDef, CST.TypeDef typeDef)
        {
            var newUsed = false;

            var state = env.InteropManager.GetTypeRepresentation(assemblyDef, typeDef).State;
            if (state == InstanceState.JavaScriptOnly || state == InstanceState.ManagedAndJavaScript)
            {
                var typeEnv =
                    Global.Environment().AddAssembly(assemblyDef).AddType(typeDef).AddSelfTypeBoundArguments();
                var methodRef = env.InteropManager.DefaultImportingConstructor(typeEnv);
                if (methodRef != null)
                {
                    // Default importing constructor is used if its type is used
                    if (ExtraUsedMethod(methodRef.QualifiedMemberName))
                        newUsed = true;
                }
            }

            

            return newUsed;
        }
Exemple #22
0
        // NOTE: May be called on invalid definitions
        public override bool MethodAlwaysUsed(CST.AssemblyDef assemblyDef, CST.TypeDef typeDef, CST.MethodDef methodDef)
        {
            if (typeDef.Style is CST.DelegateTypeStyle)
                // All the magic delegate methods are inlined by the compiler
                return false;

#if false
            if (env.AttributeHelper.MethodHasAttribute(assemblyDef, typeDef, methodDef, env.Global.CompilerGeneratedAttributeRef, false))
                return false;
#endif

            if (env.AttributeHelper.MethodHasAttribute
                (assemblyDef, typeDef, methodDef, env.AttributeHelper.IgnoreAttributeRef, true, true))
                return false;

            if (typeDef.IsModule && methodDef.IsStatic && methodDef.IsConstructor)
                return true;

            if (HasFullReflection(assemblyDef, typeDef))
                return true;

            var isUsed = default(bool);
            env.AttributeHelper.GetValueFromMethod
                (assemblyDef,
                 typeDef,
                 methodDef,
                 env.AttributeHelper.UsedAttributeRef,
                 env.AttributeHelper.TheIsUsedProperty,
                 true,
                 false,
                 ref isUsed);
            if (isUsed)
                return true;

            if (env.InteropManager.IsExported(assemblyDef, typeDef, methodDef))
                // Exported methods always used
                return true;

            return false;
        }
Exemple #23
0
 // NOTE: May be called on invalid definitions
 public override bool IsAlternateEntryPoint(CST.AssemblyDef assemblyDef, CST.TypeDef typeDef, CST.MethodDef methodDef)
 {
     return env.AttributeHelper.MethodHasAttribute
         (assemblyDef, typeDef, methodDef, env.AttributeHelper.EntryPointAttributeRef, false, false);
 }
Exemple #24
0
 private JST.Expression RecaseMethod(CST.AssemblyDef assemblyDef, CST.TypeDef typeDef, CST.MethodDef methodDef, JST.Expression script)
 {
     if (script != null)
         return script;
     var casing = default(Casing);
     attributeHelper.GetValueFromMethod
         (assemblyDef,
          typeDef,
          methodDef,
          attributeHelper.NamingAttributeRef,
          attributeHelper.TheMemberNameCasingProperty,
          true,
          false,
          ref casing);
     return new JST.Identifier(JST.Lexemes.StringToIdentifier(Recase(methodDef.Name, casing))).ToE();
 }
Exemple #25
0
 public bool IsFactory(CST.AssemblyDef assemblyDef, CST.TypeDef typeDef, CST.MethodDef methodDef)
 {
     if (!methodDef.IsStatic && methodDef.IsConstructor)
     {
         if (IsImported(assemblyDef, typeDef, methodDef))
         {
             var state = GetTypeRepresentation(assemblyDef, typeDef).State;
             switch (state)
             {
             case InstanceState.ManagedOnly:
                 {
                     // Only imported ctors in [Runtime] types can be factories
                     var isRuntime = default(bool);
                     attributeHelper.GetValueFromType
                         (assemblyDef,
                          typeDef,
                          attributeHelper.RuntimeAttributeRef,
                          attributeHelper.TheIsRuntimeProperty,
                          true,
                          false,
                          ref isRuntime);
                     return isRuntime;
                 }
             case InstanceState.Merged:
                 return true;
             case InstanceState.ManagedAndJavaScript:
             case InstanceState.JavaScriptOnly:
                 // Both managed and unmanaged instances are needed
                 break;
             default:
                 throw new ArgumentOutOfRangeException();
             }
             if (state == InstanceState.Merged)
                 return IsInlinable(assemblyDef, typeDef, methodDef, state);
         }
         // else: not improted
     }
     // else: not a ctor
     return false;
 }
Exemple #26
0
 public bool IsNoInteropResult(CST.AssemblyDef assemblyDef, CST.TypeDef typeDef, CST.MethodDef methodDef)
 {
     var isNoInterop = default(bool);
     attributeHelper.GetValueFromResult
         (assemblyDef,
          typeDef,
          methodDef,
          attributeHelper.NoInteropAttributeRef,
          attributeHelper.TheIsNoInteropProperty,
          true,
          false,
          ref isNoInterop);
     return isNoInterop;
 }
Exemple #27
0
        public override CST.InvalidInfo ImplementableMemberRef(MessageContext ctxt, CST.RootEnvironment rootEnv, CST.MemberRef memberRef)
        {
            if (memberRef.DefiningType.Style(rootEnv) is CST.DelegateTypeStyle &&
                memberRef.Name.Equals(".ctor", StringComparison.Ordinal))
                // SPECIAL CASE: Delegates are constructed by runtime, so assume .ctor is implementable
                return null;

            return null;
        }
Exemple #28
0
        public override bool PropogateExtraUsedFromMember(CST.AssemblyDef assemblyDef, CST.TypeDef typeDef, CST.MemberDef memberDef)
        {
            var newUsed = false;

            var methodDef = memberDef as CST.MethodDef;
            if (methodDef != null)
            {
                if (!methodDef.IsStatic && methodDef.IsConstructor &&
                    env.InteropManager.IsImported(assemblyDef, typeDef, methodDef) &&
                    !env.InteropManager.IsFactory(assemblyDef, typeDef, methodDef))
                {
                    // Imported instance constructor may invoke an 'importing' constructor
                    var polyMethEnv =
                        Global.Environment().AddAssembly(assemblyDef).AddType(typeDef).AddSelfTypeBoundArguments().
                            AddMethod(methodDef);
                    var methodRef = env.InteropManager.BestImportingConstructor(polyMethEnv);
                    if (methodRef != null)
                    {
                        if (ExtraUsedMethod(methodRef.QualifiedMemberName))
                            newUsed = true;
                    }
                }
            }

            return newUsed;
        }
Exemple #29
0
        // Take acccount of:
        //   - PassRootAsArgument
        //   - PassInstanceAsArgument
        //   - InlineParamsArray
        private JST.Expression AppendFinalImport(JST.NameSupply nameSupply, JST.Identifier rootId, CST.AssemblyDef assemblyDef, CST.TypeDef typeDef, CST.MethodDef methodDef, JST.Expression script, ISeq<JST.Statement> body, IImSeq<JST.Expression> arguments)
        {
            var isInstanceMethod = !(methodDef.IsStatic || methodDef.IsConstructor);
            var scriptExpectsRoot = default(bool);
            attributeHelper.GetValueFromMethod
                (assemblyDef,
                 typeDef,
                 methodDef,
                 attributeHelper.ImportAttributeRef,
                 attributeHelper.ThePassRootAsArgumentProperty,
                 true,
                 false,
                 ref scriptExpectsRoot);
            var passInstAsArg = default(bool);
            attributeHelper.GetValueFromMethod
                (assemblyDef,
                 typeDef,
                 methodDef,
                 attributeHelper.ImportAttributeRef,
                 attributeHelper.ThePassInstanceAsArgumentProperty,
                 true,
                 false,
                 ref passInstAsArg);
            var instanceIsThis = isInstanceMethod && !passInstAsArg;
            var inlineParams = default(bool);
            attributeHelper.GetValueFromMethod
                (assemblyDef,
                 typeDef,
                 methodDef,
                 attributeHelper.ImportAttributeRef,
                 attributeHelper.TheInlineParamsArrayProperty,
                 true,
                 false,
                 ref inlineParams);
            var lastArgIsParamsArray = methodDef.HasParamsArray(rootEnv) && inlineParams;

            var funcScript = script as JST.FunctionExpression;

            var nextArg = 0;
            var instArg = default(JST.Expression);
            if (instanceIsThis)
            {
                // Instance argument will be the first arg to 'call' or 'apply', or the target of a '.' call.
                instArg = arguments[nextArg++];
                if (lastArgIsParamsArray && !instArg.IsDuplicatable)
                {
                    // Make sure instance argument is evaluated before the remaining arguments
                    var instId = nameSupply.GenSym();
                    body.Add(JST.Statement.Var(instId, instArg));
                    instArg = instId.ToE();
                }
            }
            else
            {
                if (lastArgIsParamsArray)
                    instArg = new JST.NullExpression();
            }

            var knownArgs = 0;
            var call = default(JST.Expression);

            if (lastArgIsParamsArray)
            {
                // We mush build script args at runtime
                var argsId = nameSupply.GenSym();
                body.Add(JST.Statement.Var(argsId, new JST.ArrayLiteral()));
                if (scriptExpectsRoot)
                {
                    body.Add(JST.Statement.DotCall(argsId.ToE(), Constants.push, rootId.ToE()));
                    knownArgs++;
                }
                while (nextArg < arguments.Count - 1)
                {
                    body.Add(JST.Statement.DotCall(argsId.ToE(), Constants.push, arguments[nextArg++]));
                    knownArgs++;
                }
                var arrArg = arguments[nextArg];
                if (!arrArg.IsDuplicatable)
                {
                    var arrId = nameSupply.GenSym();
                    body.Add(JST.Statement.Var(arrId, arrArg));
                    arrArg = arrId.ToE();
                }
                var iId = nameSupply.GenSym();
                body.Add
                    (new JST.IfStatement
                         (JST.Expression.IsNotNull(arrArg),
                          new JST.Statements
                              (new JST.ForStatement
                                   (new JST.ForVarLoopClause
                                        (iId,
                                         new JST.NumericLiteral(0),
                                         new JST.BinaryExpression
                                             (iId.ToE(),
                                              JST.BinaryOp.LessThan,
                                              JST.Expression.Dot(arrArg, Constants.length)),
                                         new JST.UnaryExpression(iId.ToE(), JST.UnaryOp.PostIncrement)),
                                    new JST.Statements
                                        (JST.Statement.DotCall
                                             (argsId.ToE(), Constants.push, new JST.IndexExpression(arrArg, iId.ToE())))))));

                if (funcScript != null)
                {
                    // var args = ...; var x = script; x.apply(this/null, args)
                    var scriptId = nameSupply.GenSym();
                    body.Add(JST.Statement.Var(scriptId, funcScript));
                    call = JST.Expression.DotCall(scriptId.ToE(), Constants.apply, instArg, argsId.ToE());
                }
                else
                {
                    if (instanceIsThis)
                    {
                        // var args = ...; (this.script).apply(this, args);
                        call = JST.Expression.DotCall
                            (JST.Expression.Dot(instArg, JST.Expression.ExplodePath(script)),
                             Constants.apply,
                             instArg,
                             argsId.ToE());
                    }
                    else
                    {
                        // var args = ...; script.apply(null, args)
                        call = JST.Expression.DotCall(script, Constants.apply, instArg, argsId.ToE());
                    }
                }
            }
            else
            {
                var callArgs = new Seq<JST.Expression>();
                if (instanceIsThis && funcScript != null)
                    callArgs.Add(instArg);
                if (scriptExpectsRoot)
                {
                    callArgs.Add(rootId.ToE());
                    knownArgs++;
                }
                while (nextArg < arguments.Count)
                {
                    callArgs.Add(arguments[nextArg++]);
                    knownArgs++;
                }
                if (instanceIsThis)
                {
                    if (funcScript != null)
                    {
                        // var x = script; x.call(this, arg1, ..., argn)
                        var scriptId = nameSupply.GenSym();
                        body.Add(JST.Statement.Var(scriptId, funcScript));
                        call = JST.Expression.DotCall(scriptId.ToE(), Constants.call, callArgs);
                    }
                    else
                        // this.script(arg1, ..., angn)
                        call = new JST.CallExpression
                            (JST.Expression.Dot(instArg, JST.Expression.ExplodePath(script)), callArgs);
                }
                else
                    // script(arg1, ..., argn)
                    call = new JST.CallExpression(script, callArgs);
            }

            if (funcScript != null)
            {
                if (funcScript.Parameters.Count < knownArgs)
                {
                    var ctxt = CST.MessageContextBuilders.Member(env.Global, assemblyDef, typeDef, methodDef);
                    env.Log(new InvalidInteropMessage(ctxt, "script accepts too few arguments"));
                    throw new DefinitionException();
                }
            }

            return call;
        }
Exemple #30
0
 public bool IsStatic(CST.AssemblyDef assemblyDef, CST.TypeDef typeDef, CST.MethodDef methodDef)
 {
     return methodDef.IsStatic || IsFactory(assemblyDef, typeDef, methodDef);
 }