예제 #1
1
파일: Traces.cs 프로젝트: modulexcite/IL2JS
 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);
 }
예제 #2
0
파일: Traces.cs 프로젝트: modulexcite/IL2JS
 public void AddType(MessageContext ctxt)
 {
     var trace = Parent.Parent;
     var name = Type.QualifiedTypeName(trace.Parent.Env.Global, Parent.Assembly);
     if (trace.Parent.FirstOccuranceOfType(ctxt, name, trace))
         IncludeType = true;
 }
예제 #3
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();
        }
예제 #4
0
파일: Traces.cs 프로젝트: modulexcite/IL2JS
 private TypeTrace ResolveTypeTrace(MessageContext ctxt, string typeName)
 {
     var nm = CST.TypeName.FromReflectionName(typeName);
     if (nm != null)
     {
         var typeDef = Assembly.ResolveType(nm);
         if (typeDef != null)
             return ResolveTypeTrace(typeDef);
     }
     Parent.Parent.Env.Log(new InvalidTraceMessage(ctxt, "no such type"));
     throw new ExitException();
 }
예제 #5
0
파일: Traces.cs 프로젝트: modulexcite/IL2JS
 public void AddMethod(MessageContext ctxt, string methodName)
 {
     var trace = Parent.Parent;
     foreach (var methodDef in Type.Members.OfType<CST.MethodDef>().Where(m => m.IsUsed && m.Invalid == null))
     {
         var nm = CST.CSTWriter.WithAppend
             (trace.Parent.Env.Global, CST.WriterStyle.Uniform, methodDef.MethodSignature.Append);
         if (methodName.Equals(nm, StringComparison.Ordinal))
         {
             AddMethod(ctxt, methodDef);
             return;
         }
     }
     trace.Parent.Env.Log(new InvalidTraceMessage(ctxt, "no such method"));
     throw new ExitException();
 }
예제 #6
0
 public static MessageContext Type(MessageContext parent, CCI.TypeNode type)
 {
     var loc = default(Location);
     if (type.SourceContext.Document != null)
         loc = type.SourceContext.ToLocation();
     else if (type.Name != null && type.Name.SourceContext.Document != null)
         loc = type.Name.SourceContext.ToLocation();
     return new MessageContext
         (parent,
          loc,
          sb =>
          {
              sb.Append("Type ");
              sb.Append(type.FullName);
          });
 }
예제 #7
0
        public static MessageContext Member(MessageContext parent, CCI.Member member)
        {
            var loc = default(Location);
            if (member.SourceContext.Document != null)
                loc = member.SourceContext.ToLocation();
            else if (member.Name != null && member.Name.SourceContext.Document != null)
                loc = member.Name.SourceContext.ToLocation();

            return new MessageContext
                (parent,
                 loc,
                 sb =>
                 {
                     sb.Append("Member ");
                     sb.Append(member.FullName);
                 });
        }
예제 #8
0
 public static MessageContext Method(MessageContext parent, CCI.Method method)
 {
     var loc = default(Location);
     if (method.SourceContext.Document != null)
         loc = method.SourceContext.ToLocation();
     else if (method.Name != null && method.Name.SourceContext.Document != null)
         loc = method.Name.SourceContext.ToLocation();
     else if (method.Instructions != null && method.Instructions.Count > 1 &&
              method.Instructions[1].SourceContext.Document != null)
         loc = method.Instructions[1].SourceContext.ToLocation();
     return new MessageContext
         (parent,
          loc,
          sb =>
          {
              sb.Append("Method ");
              sb.Append(method.FullName);
          });
 }
예제 #9
0
 public InvalidCustomAttribute(MessageContext ctxt, AssemblyName referencingAssemblyName, TypeRef typeRef, string message)
     : base(ctxt, Severity.Warning, "1027")
 {
     ReferencingAssemblyName = referencingAssemblyName;
     TypeRef = typeRef;
     Message = message;
 }
예제 #10
0
 public InvalidMemberDef(MessageContext ctxt, string message)
     : base(ctxt, Severity.Warning, "1025")
 {
     Message = message;
 }
예제 #11
0
 public InvalidTypeDef(MessageContext ctxt, string message)
     : base(ctxt, Severity.Warning, "1023")
 {
     Message = message;
 }
예제 #12
0
 public InvalidMemberName(MessageContext ctxt, QualifiedMemberName name, string message)
     : base(ctxt, Severity.Warning, "1021")
 {
     Name = name;
     Message = message;
 }
예제 #13
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;
        }
예제 #14
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;
 }
예제 #15
0
 private bool LastArgIsParamsArray(MessageContext ctxt, CCI.Method methodDefn)
 {
     var parameters = methodDefn.Parameters;
     if (parameters != null && parameters.Count > 0)
     {
         var p = parameters[parameters.Count - 1];
         var attr = p.GetParamArrayAttribute();
         if (attr != null)
             return true;
     }
     return false;
 }
예제 #16
0
 private void CheckTypeIsImportableExportable(MessageContext ctxt, CST.MethodEnvironment methEnv, CST.TypeRef type)
 {
     var s = type.Style(methEnv);
     if (s is CST.UnmanagedPointerTypeStyle)
     {
         env.Log(new InvalidInteropMessage(ctxt, "Cannot import/export unmanaged pointers"));
         throw new DefinitionException();
     }
     if (s is CST.CodePointerTypeStyle)
     {
         env.Log(new InvalidInteropMessage(ctxt, "Cannot import/export code pointers"));
         throw new DefinitionException();
     }
 }
예제 #17
0
 public TypeRepresentation GetTypeRepresentation(MessageContext ctxt, CST.RootEnvironment rootEnv, CST.TypeRef typeRef)
 {
     var typeEnv = typeRef.Enter(rootEnv);
     return GetTypeRepresentation(typeEnv.Assembly, typeEnv.Type);
 }
예제 #18
0
        public bool IsImported(MessageContext ctxt, CCI.Method methodDefn)
        {
            if (methodDefn.DeclaringMember != null)
            {
                var declProp = methodDefn.DeclaringMember as CCI.Property;
                if (declProp != null)
                {
                    if (declProp.Getter != null && declProp.Setter != null)
                    {
                        var n = 0;
                        if (interopTypes.HasAttribute(declProp.Getter, env.ImportAttributeType, false))
                            n++;
                        if (interopTypes.HasAttribute(declProp.Setter, env.ImportAttributeType, false))
                            n++;
                        if (n == 1)
                        {
                            env.Log(new InvalidInteropMessage
                                (RewriterMsgContext.Property(ctxt, declProp),
                                 "properties with getters and setters must be imported simultaneously"));
                            throw new DefinitionException();
                        }
                    }
                }
                else
                {
                    var declEvnt = methodDefn.DeclaringMember as CCI.Event;
                    if (declEvnt != null)
                    {
                        if (declEvnt.HandlerAdder != null && declEvnt.HandlerRemover != null)
                        {
                            var n = 0;
                            if (interopTypes.HasAttribute
                                (declEvnt.HandlerAdder, env.ImportAttributeType, false))
                                n++;
                            if (interopTypes.HasAttribute
                                (declEvnt.HandlerRemover, env.ImportAttributeType, false))
                                n++;
                            if (n == 1)
                            {
                                env.Log(new InvalidInteropMessage
                                    (RewriterMsgContext.Property(ctxt, declProp),
                                     "events with adders and removers must be imported simultaneously"));
                                throw new DefinitionException();
                            }
                        }
                    }
                }
            }

            if (IsExtern(methodDefn))
            {
                if (interopTypes.HasAttribute(methodDefn, env.ImportAttributeType, true))
                {
                    if (interopTypes.HasAttribute(methodDefn, env.DllImportAttributeType, false))
                    {
                        env.Log(new InvalidInteropMessage
                            (RewriterMsgContext.Method(methodDefn), "cannot mix 'Import' and 'DllImport' attributes"));
                        throw new DefinitionException();
                    }
                    return true;
                }
                else
                    return false;
            }
            else
            {
                if (interopTypes.HasAttribute(methodDefn, env.ImportAttributeType, false))
                {
                    if (methodDefn.DeclaringMember == null)
                    {
                        env.Log(new InvalidInteropMessage
                            (RewriterMsgContext.Method(methodDefn),
                             "cannot Import a method which already has an implementation"));
                        throw new DefinitionException();
                    }
                    // else: C# doesn't allow extern properties, so be forgiving here
                    return true;
                }
                return false;
            }
        }
예제 #19
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;
 }
예제 #20
0
        // Take acccount of
        //   - PassRootAsArgument
        //   - PassInstanceAsArgument
        //   - InlineParamsArray
        private ImportMethodInfo FinalImportScript(MessageContext ctxt, Func<JST.Identifier> gensym, JST.Identifier rootId, CCI.Method methodDefn, JST.Expression script, bool isNew)
        {
            if (script == null)
                throw new InvalidOperationException("expecting default script value");

            var lastArgIsParamsArray = LastArgIsParamsArray(ctxt, methodDefn) && interopTypes.GetValue(ctxt, methodDefn, env.ImportAttributeType, interopTypes.TheInlineParamsArrayProperty);
            var methodArity = Arity(methodDefn);
            var isInstanceMethod = !(methodDefn.IsStatic || methodDefn is CCI.InstanceInitializer);
            var scriptExpectsRoot = interopTypes.GetValue
                (ctxt, methodDefn, env.ImportAttributeType, interopTypes.ThePassRootAsArgumentProperty);
            var instanceIsThis = isInstanceMethod &&
                                 !interopTypes.GetValue
                                      (ctxt,
                                       methodDefn,
                                       env.ImportAttributeType,
                                       interopTypes.ThePassInstanceAsArgumentProperty);
            var expectedScriptArity = methodArity - (lastArgIsParamsArray ? 1 : 0) + (scriptExpectsRoot ? 1 : 0) -
                                      (instanceIsThis ? 1 : 0);
            CheckScriptArity(ctxt, methodDefn, script, expectedScriptArity);

            var function = default(JST.FunctionExpression);
            if (gensym != null)
            {
                var parameters = new Seq<JST.Identifier>();
                var body = new Seq<JST.Statement>();

                var callArgs = new Seq<JST.Expression>();

                if (lastArgIsParamsArray)
                {
                    var argsId = gensym();
                    body.Add(JST.Statement.Var(argsId, new JST.ArrayLiteral()));

                    if (scriptExpectsRoot)
                        body.Add(JST.Statement.DotCall(argsId.ToE(), Constants.push, rootId.ToE()));

                    if (!isInstanceMethod)
                        callArgs.Add(new JST.NullExpression());

                    for (var i = 0; i < methodArity; i++)
                    {
                        var id = gensym();
                        parameters.Add(id);
                        if (isInstanceMethod && i == 0)
                        {
                            if (instanceIsThis)
                                callArgs.Add(id.ToE());
                            else
                            {
                                callArgs.Add(new JST.NullExpression());
                                body.Add(JST.Statement.DotCall(argsId.ToE(), Constants.push, id.ToE()));
                            }
                        }
                        else if (i == methodArity - 1)
                        {
                            var iId = gensym();
                            body.Add
                                (new JST.IfStatement
                                     (JST.Expression.IsNotNull(id.ToE()),
                                      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(id.ToE(), Constants.length)),
                                                     new JST.UnaryExpression(iId.ToE(), JST.UnaryOp.PostIncrement)),
                                                new JST.Statements
                                                    (JST.Statement.DotCall
                                                         (argsId.ToE(),
                                                          Constants.push,
                                                          new JST.IndexExpression(id.ToE(), iId.ToE())))))));
                        }
                        else
                            body.Add(JST.Statement.DotCall(argsId.ToE(), Constants.push, id.ToE()));
                    }
                    if (script is JST.FunctionExpression)
                    {
                        var funcId = gensym();
                        body.Add(JST.Statement.Var(funcId, script));
                        script = JST.Expression.Dot(funcId.ToE(), Constants.apply);
                    }
                    else
                        script = JST.Expression.Dot(script, Constants.apply);
                    callArgs.Add(argsId.ToE());
                }
                else
                {
                    if (scriptExpectsRoot)
                        callArgs.Add(rootId.ToE());

                    for (var i = 0; i < methodArity; i++)
                    {
                        var id = gensym();
                        parameters.Add(id);
                        if (i == 0 && instanceIsThis)
                        {
                            if (script is JST.FunctionExpression)
                            {
                                callArgs.Insert(0, id.ToE());
                                var funcId = gensym();
                                body.Add(JST.Statement.Var(funcId, script));
                                script = JST.Expression.Dot(funcId.ToE(), Constants.call);
                            }
                            else
                                script = JST.Expression.Dot(id.ToE(), JST.Expression.ExplodePath(script));
                        }
                        else
                            callArgs.Add(id.ToE());
                    }
                }

                var exp = (JST.Expression)new JST.CallExpression(script, callArgs);
                if (isNew)
                    exp = new JST.NewExpression(exp);

                if (ReturnType(methodDefn) == null)
                    body.Add(new JST.ExpressionStatement(exp));
                else
                    body.Add(new JST.ReturnStatement(exp));

                function = new JST.FunctionExpression(parameters, new JST.Statements(body));
            }
            return new ImportMethodInfo { MethodDefn = methodDefn, Script = function };
        }
예제 #21
0
 protected Message(MessageContext ctxt, Severity severity, string id)
 {
     Context = ctxt;
     Severity = severity;
     Id = id;
 }
예제 #22
0
 private void CheckParameterAndReturnTypesAreImportableExportable(MessageContext ctxt, CCI.Method methodDefn)
 {
     var subCtxt = RewriterMsgContext.Method(ctxt, methodDefn);
     for (var i = 0; i < methodDefn.Parameters.Count; i++)
         CheckImportableExportable(RewriterMsgContext.Argument(subCtxt, i), methodDefn.Parameters[i].Type);
     if (ReturnType(methodDefn) != null)
         CheckImportableExportable(RewriterMsgContext.Result(subCtxt), ReturnType(methodDefn));
 }
예제 #23
0
 public InvalidTypeRef(MessageContext ctxt, TypeRef type, string message)
     : base(ctxt, Severity.Warning, "1022")
 {
     Type = type;
     Message = message;
 }
예제 #24
0
        public ImportMethodInfo ImportInfo(MessageContext ctxt, Func<JST.Identifier> gensym, JST.Identifier rootId, CCI.Method methodDefn)
        {
            if (!IsImported(ctxt, methodDefn))
                return null;

            if (gensym != null)
                CheckParameterAndReturnTypesAreImportableExportable(ctxt, methodDefn);

            var methodArity = Arity(methodDefn);
            var script = interopTypes.GetValue(ctxt, methodDefn, env.ImportAttributeType, interopTypes.TheScriptProperty);

            if (methodDefn is CCI.InstanceInitializer)
            {
                // XREF1171
                // Constructor
                if (script == null)
                {
                    switch (
                        interopTypes.GetValue
                            (ctxt, methodDefn, env.ImportAttributeType, interopTypes.TheCreationProperty))
                    {
                        case Creation.Constructor:
                            script = PrefixName(ctxt, methodDefn, null, false);
                            break;
                        case Creation.Object:
                            if (methodArity > 0)
                            {
                                env.Log(new InvalidInteropMessage
                                    (RewriterMsgContext.Method(ctxt, methodDefn),
                                     "imported constructors for object literals cannot have arguments"));
                                throw new DefinitionException();
                            }
                            script = Constants.Object.ToE();
                            break;
                        case Creation.Array:
                            script = Constants.Array.ToE();
                            break;
                        default:
                            throw new ArgumentOutOfRangeException();
                    }
                    return FinalImportScript(ctxt, gensym, rootId, methodDefn, script, true);
                }
                else if (script is JST.FunctionExpression)
                    return FinalImportScript(ctxt, gensym, rootId, methodDefn, script, false);
                else
                {
                    script = PrefixName(ctxt, methodDefn, script, false);
                    return FinalImportScript(ctxt, gensym, rootId, methodDefn, script, true);
                }
            }
            else
            {
                if (methodDefn.DeclaringMember != null)
                {
                    var isOnMethod = interopTypes.HasAttribute(methodDefn, env.ImportAttributeType, false);
                    var localScript = isOnMethod ? interopTypes.GetValue(ctxt, methodDefn, env.ImportAttributeType, interopTypes.TheScriptProperty, false) : default(JST.Expression);

                    var prop = methodDefn.DeclaringMember as CCI.Property;
                    if (prop != null)
                    {
                        // XREF1187
                        if (methodDefn == prop.Getter)
                        {
                            // Getter
                            if (isOnMethod)
                            {
                                script = PrefixName
                                    (ctxt,
                                     methodDefn,
                                     GetterSetterAdderRemoverNameFromMethod(ctxt, methodDefn, "get", localScript), false);
                                return FinalImportScript(ctxt, gensym, rootId, methodDefn, script, false);
                            }
                            else if (script != null && script is JST.FunctionExpression)
                            {
                                env.Log(new InvalidInteropMessage
                                    (RewriterMsgContext.Method(ctxt, methodDefn),
                                     "property import script cannot be a function"));
                                throw new DefinitionException();
                            }
                            else
                            {
                                var function = default(JST.FunctionExpression);
                                if (gensym != null)
                                {
                                    var parameters = new Seq<JST.Identifier>();
                                    var body = new Seq<JST.Statement>();

                                    for (var i = 0; i < methodArity; i++)
                                        parameters.Add(gensym());
                                    if (script == null && methodArity == 2 && !methodDefn.IsStatic)
                                        body.Add
                                            (new JST.ReturnStatement
                                                 (new JST.IndexExpression
                                                      (parameters[0].ToE(), parameters[1].ToE())));
                                    else
                                    {
                                        script = PrefixName
                                            (ctxt, methodDefn, RecasePropertyEvent(ctxt, methodDefn, script), false);
                                        if (methodDefn.IsStatic && methodArity == 0)
                                            body.Add(new JST.ReturnStatement(script));
                                        else if (!methodDefn.IsStatic && methodArity == 1)
                                            body.Add
                                                (new JST.ReturnStatement
                                                     (JST.Expression.Dot
                                                          (parameters[0].ToE(),
                                                           JST.Expression.ExplodePath(script))));
                                        else
                                        {
                                            env.Log(new InvalidInteropMessage
                                                (RewriterMsgContext.Method(ctxt, methodDefn),
                                                 "additional getter parameters not supported for default getters"));
                                            throw new DefinitionException();
                                        }
                                    }
                                    function = new JST.FunctionExpression(parameters, new JST.Statements(body));
                                }
                                return new ImportMethodInfo { MethodDefn = methodDefn, Script = function };
                            }
                        }
                        else if (methodDefn == prop.Setter)
                        {
                            // Setter
                            if (isOnMethod)
                            {
                                script = PrefixName
                                    (ctxt,
                                     methodDefn,
                                     GetterSetterAdderRemoverNameFromMethod(ctxt, methodDefn, "set", localScript), false);
                                return FinalImportScript(ctxt, gensym, rootId, methodDefn, script, false);
                            }
                            else if (script != null && script is JST.FunctionExpression)
                            {
                                env.Log(new InvalidInteropMessage
                                    (RewriterMsgContext.Method(ctxt, methodDefn),
                                     "property import script cannot be a function"));
                                throw new DefinitionException();
                            }
                            else
                            {
                                var function = default(JST.FunctionExpression);
                                if (gensym != null)
                                {
                                    var parameters = new Seq<JST.Identifier>();
                                    var body = new Seq<JST.Statement>();

                                    for (var i = 0; i < methodArity; i++)
                                        parameters.Add(gensym());
                                    if (script == null && methodArity == 3 && !methodDefn.IsStatic)
                                        body.Add
                                            (JST.Statement.IndexAssignment
                                                 (parameters[0].ToE(),
                                                  parameters[1].ToE(),
                                                  parameters[2].ToE()));
                                    else
                                    {
                                        script = PrefixName
                                            (ctxt, methodDefn, RecasePropertyEvent(ctxt, methodDefn, script), false);
                                        if (methodDefn.IsStatic && methodArity == 1)
                                            body.Add
                                                (JST.Statement.Assignment(script, parameters[0].ToE()));
                                        else if (!methodDefn.IsStatic && methodArity == 2)
                                            body.Add
                                                (JST.Statement.Assignment
                                                     (JST.Expression.Dot
                                                          (parameters[0].ToE(),
                                                           JST.Expression.ExplodePath(script)),
                                                      parameters[1].ToE()));
                                        else
                                        {
                                            env.Log(new InvalidInteropMessage
                                                (RewriterMsgContext.Method(ctxt, methodDefn),
                                                 "additional setter parameters not supported for default setters"));
                                            throw new DefinitionException();
                                        }
                                    }
                                    function = new JST.FunctionExpression(parameters, new JST.Statements(body));
                                }
                                return new ImportMethodInfo { MethodDefn = methodDefn, Script = function };
                            }
                        }
                        else
                            throw new InvalidOperationException();
                    }
                    else
                    {
                        var evnt = methodDefn.DeclaringMember as CCI.Event;
                        if (evnt != null)
                        {
                            // XREF1201
                            if (methodDefn == evnt.HandlerAdder)
                            {
                                // Adder
                                if (isOnMethod)
                                {
                                    script = PrefixName
                                        (ctxt,
                                         methodDefn,
                                         GetterSetterAdderRemoverNameFromMethod(ctxt, methodDefn, "add", localScript), false);
                                    return FinalImportScript(ctxt, gensym, rootId, methodDefn, script, false);
                                }
                                else if (script != null && script is JST.FunctionExpression)
                                {
                                    env.Log(new InvalidInteropMessage
                                        (RewriterMsgContext.Method(ctxt, methodDefn),
                                         "event import script cannot be a function"));
                                    throw new DefinitionException();
                                }
                                else
                                {
                                    var function = default(JST.FunctionExpression);
                                    if (gensym != null)
                                    {
                                        var parameters = new Seq<JST.Identifier>();
                                        var body = new Seq<JST.Statement>();

                                        for (var i = 0; i < methodArity; i++)
                                            parameters.Add(gensym());
                                        script = PrefixName
                                            (ctxt, methodDefn, RecasePropertyEvent(ctxt, methodDefn, script), false);
                                        if (methodDefn.IsStatic)
                                            body.Add
                                                (JST.Statement.Assignment(script, parameters[0].ToE()));
                                        else
                                            body.Add
                                                (JST.Statement.Assignment
                                                     (JST.Expression.Dot
                                                          (parameters[0].ToE(),
                                                           JST.Expression.ExplodePath(script)),
                                                      parameters[1].ToE()));
                                        function = new JST.FunctionExpression(parameters, new JST.Statements(body));
                                    }
                                    return new ImportMethodInfo { MethodDefn = methodDefn, Script = function };
                                }
                            }
                            else if (methodDefn == evnt.HandlerRemover)
                            {
                                // Remover
                                if (isOnMethod)
                                {
                                    script = PrefixName
                                        (ctxt,
                                         methodDefn,
                                         GetterSetterAdderRemoverNameFromMethod(ctxt, methodDefn, "remove", localScript), false);
                                    return FinalImportScript(ctxt, gensym, rootId, methodDefn, script, false);
                                }
                                else if (script != null && script is JST.FunctionExpression)
                                {
                                    env.Log(new InvalidInteropMessage
                                        (RewriterMsgContext.Method(ctxt, methodDefn),
                                         "event import script cannot be a function"));
                                    throw new DefinitionException();
                                }
                                else
                                {
                                    var function = default(JST.FunctionExpression);
                                    if (gensym != null)
                                    {
                                        var parameters = new Seq<JST.Identifier>();
                                        var body = new Seq<JST.Statement>();

                                        for (var i = 0; i < methodArity; i++)
                                            parameters.Add(gensym());
                                        script = PrefixName
                                            (ctxt, methodDefn, RecasePropertyEvent(ctxt, methodDefn, script), false);
                                        if (methodDefn.IsStatic)
                                            body.Add
                                                (JST.Statement.Assignment(script, parameters[0].ToE()));
                                        else
                                            body.Add
                                                (JST.Statement.Assignment
                                                     (JST.Expression.Dot
                                                          (parameters[0].ToE(),
                                                           JST.Expression.ExplodePath(script)),
                                                      parameters[1].ToE()));

                                        function = new JST.FunctionExpression(parameters, new JST.Statements(body));
                                    }
                                    return new ImportMethodInfo { MethodDefn = methodDefn, Script = function };
                                }
                            }
                            else
                                throw new InvalidOperationException();
                        }
                        else
                            throw new InvalidOperationException();
                    }
                }
                else
                {
                    // XREF1153
                    // Normal method
                    script = PrefixName(ctxt, methodDefn, RecaseMember(ctxt, methodDefn, script), false);
                    return FinalImportScript(ctxt, gensym, rootId, methodDefn, script, false);
                }
            }
        }
예제 #25
0
 public InvalidMemberRef(MessageContext ctxt, MemberRef member, string message)
     : base(ctxt, Severity.Warning, "1024")
 {
     Member = member;
     Message = message;
 }
예제 #26
0
        // ----------------------------------------------------------------------
        // Exported methods
        // ----------------------------------------------------------------------

        public bool IsExported(MessageContext ctxt, CCI.Method methodDefn)
        {
            var isExtern = IsExtern(methodDefn);
            // Allow attributes to be inherited only if the method has a definition
            // (This way we can place an 'Export' attribute in an outer scope even if there are
            //  extern methods in that scope.)
            if (interopTypes.HasAttribute(methodDefn, env.ExportAttributeType, !isExtern) &&
                !interopTypes.HasAttribute(methodDefn, env.NotExportedAttributeType, false))
                return true;

#if false
            if (methodDefn.IsVirtual && methodDefn.OverriddenMethod != null && !isExtern)
            {
                var origDefn = methodDefn;
                do
                    origDefn = origDefn.OverriddenMethod;
                while (origDefn.IsVirtual && origDefn.OverriddenMethod != null);
                if (origDefn.DeclaringType != env.ObjectType && IsImported(ctxt, origDefn))
                    return true;
            }
#endif
            return false;
        }
예제 #27
0
 public InvalidInstruction(MessageContext ctxt, Instruction instruction, string message)
     : base(ctxt, Severity.Warning, "1026")
 {
     Instruction = instruction;
     Message = message;
 }
예제 #28
0
        // Take account of:
        //  - BindToPrototype
        //  - PassRootAsArgument
        //  - PassInstanceAsArgument
        //  - InlineParamsArray
        private ExportMethodInfo FinalExportInfo(MessageContext ctxt, Func<JST.Identifier> gensym, JST.Identifier rootId, CCI.Method methodDefn, JST.Expression script)
        {
            if (script == null)
                throw new InvalidOperationException("expecting default script value");

            var isInstance = !methodDefn.IsStatic && !(methodDefn is CCI.InstanceInitializer);
            if (isInstance)
            {
                var declType = methodDefn.DeclaringType;
                if (declType.IsValueType)
                {
                    env.Log(new InvalidInteropMessage
                        (RewriterMsgContext.Method(ctxt, methodDefn), "cannot export instance methods from value types"));
                    throw new DefinitionException();
                }
            }

            var lastArgIsParamsArray = LastArgIsParamsArray(ctxt, methodDefn) &&
                                       interopTypes.GetValue
                                           (ctxt,
                                            methodDefn,
                                            env.ExportAttributeType,
                                            interopTypes.TheInlineParamsArrayProperty);
            var isPassRoot = interopTypes.GetValue
                (ctxt, methodDefn, env.ExportAttributeType, interopTypes.ThePassRootAsArgumentProperty);
            var isProto = interopTypes.GetValue
                (ctxt, methodDefn, env.ExportAttributeType, interopTypes.TheBindToPrototypeProperty);
            var isPassInstance = interopTypes.GetValue
                (ctxt, methodDefn, env.ExportAttributeType, interopTypes.ThePassInstanceAsArgumentProperty);
            var bindToInstance = isInstance && !isProto;
            var captureThis = isInstance && !isPassInstance;

            var expectedScriptArity = (isPassRoot ? 1 : 0) + (bindToInstance ? 1 : 0) + 1;
            CheckScriptArity(ctxt, methodDefn, script, expectedScriptArity);

            var function = default(JST.FunctionExpression);

            if (gensym != null)
            {
                var parameters = new Seq<JST.Identifier>();
                var body = new Seq<JST.Statement>();

                var callArgs = new Seq<JST.Expression>();
                if (isPassRoot)
                    callArgs.Add(rootId.ToE());
                var instArgId = default(JST.Identifier);
                if (bindToInstance)
                {
                    instArgId = gensym();
                    parameters.Add(instArgId);
                    callArgs.Add(instArgId.ToE());
                }
                var funcArgId = gensym();
                parameters.Add(funcArgId);

                if (captureThis || lastArgIsParamsArray)
                {
                    var innerParameters = new Seq<JST.Identifier>();
                    var innerBody = new Seq<JST.Statement>();
                    var innerArgs = new Seq<JST.Expression>();
                    var methodArity = Arity(methodDefn);
                    for (var i = 0; i < methodArity; i++)
                    {
                        if (i == 0 && captureThis)
                            innerArgs.Add(new JST.ThisExpression());
                        else if (i == methodArity - 1 && lastArgIsParamsArray)
                        {
                            var iId = gensym();
                            var arrId = gensym();
                            innerBody.Add(JST.Statement.Var(arrId, new JST.ArrayLiteral()));
                            innerBody.Add
                                (new JST.ForStatement
                                     (new JST.ForVarLoopClause
                                          (iId,
                                           new JST.NumericLiteral(methodArity - 1),
                                           new JST.BinaryExpression
                                               (iId.ToE(),
                                                JST.BinaryOp.LessThan,
                                                JST.Expression.Dot(Constants.arguments.ToE(), Constants.length)),
                                           new JST.UnaryExpression(iId.ToE(), JST.UnaryOp.PostIncrement)),
                                      new JST.Statements(JST.Statement.DotCall
                                          (arrId.ToE(),
                                           Constants.push,
                                           new JST.IndexExpression(Constants.arguments.ToE(), iId.ToE())))));
                            innerArgs.Add(arrId.ToE());
                        }
                        else
                        {
                            var innerArgId = gensym();
                            innerParameters.Add(innerArgId);
                            innerArgs.Add(innerArgId.ToE());
                        }
                    }
                    if (ReturnType(methodDefn) == null)
                    {
                        innerBody.Add(JST.Statement.Call(funcArgId.ToE(), innerArgs));
                        innerBody.Add(new JST.ReturnStatement());
                    }
                    else
                        innerBody.Add(new JST.ReturnStatement(new JST.CallExpression(funcArgId.ToE(), innerArgs)));
                    var innerFunction = new JST.FunctionExpression(innerParameters, new JST.Statements(innerBody));
                    callArgs.Add(innerFunction);
                }
                else
                    callArgs.Add(funcArgId.ToE());

                if (script is JST.FunctionExpression)
                    body.Add(new JST.ExpressionStatement(new JST.CallExpression(script, callArgs)));
                else
                {
                    var i = 0;
                    if (bindToInstance)
                        script = JST.Expression.Dot(callArgs[i++], JST.Expression.ExplodePath(script));
                    EnsurePathExists(body, script, !bindToInstance);
                    body.Add(JST.Statement.Assignment(script, callArgs[i]));
                }

                function = new JST.FunctionExpression(parameters, new JST.Statements(body));
            }

            return new ExportMethodInfo { MethodDefn = methodDefn, Script = function, BindToInstance = bindToInstance };
        }
예제 #29
0
 public UnimplementableUsedTypeMessage(MessageContext ctxt, InvalidInfo info)
     : base(ctxt, Severity.Error, "1028")
 {
     Info = info;
 }
예제 #30
0
 public MessageContext(MessageContext parent, Location loc, Action<StringBuilder> append)
 {
     Parent = parent;
     Loc = loc;
     this.append = append;
 }