Example #1
0
        internal static void CheckMemberAccess(SemanticModel model, MemberAccessExpressionSyntax node, IMethodSymbol callerSym)
        {
            var esym     = model.GetSymbolInfoEx(node).Symbol as IEventSymbol;
            var psym     = model.GetSymbolInfoEx(node).Symbol as IPropertySymbol;
            var fsym     = model.GetSymbolInfoEx(node).Symbol as IFieldSymbol;
            var msym     = model.GetSymbolInfoEx(node).Symbol as IMethodSymbol;
            var nodeType = model.GetTypeInfoEx(node).Type;

            bool             isExtern  = false;
            INamedTypeSymbol classType = null;

            if (null != esym && !SymbolTable.Instance.IsCs2DslSymbol(esym))
            {
                isExtern  = true;
                classType = esym.ContainingType;
                Logger.Instance.Log(node, "unsupported extern event '{0}.{1}' !", ClassInfo.GetFullName(esym.ContainingType), esym.Name);
            }
            if (null != psym && !SymbolTable.Instance.IsCs2DslSymbol(psym))
            {
                isExtern  = true;
                classType = psym.ContainingType;
                if (SymbolTable.Instance.IsIllegalProperty(psym))
                {
                    Logger.Instance.Log(node, "unsupported extern property '{0}.{1}' !", ClassInfo.GetFullName(psym.ContainingType), psym.Name);
                }
            }
            if (null != fsym && !SymbolTable.Instance.IsCs2DslSymbol(fsym))
            {
                isExtern  = true;
                classType = fsym.ContainingType;
                if (SymbolTable.Instance.IsIllegalField(fsym))
                {
                    Logger.Instance.Log(node, "unsupported extern field '{0}.{1}' !", ClassInfo.GetFullName(fsym.ContainingType), fsym.Name);
                }
            }
            if (null != msym && !(node.Parent is InvocationExpressionSyntax) && !SymbolTable.Instance.IsCs2DslSymbol(msym.ContainingType))
            {
                if (SymbolTable.Instance.IsIllegalMethod(msym))
                {
                    Logger.Instance.Log(node, "unsupported extern event '{0}.{1}' !", ClassInfo.GetFullName(msym.ContainingType), msym.Name);
                }
            }
            if (isExtern && null != nodeType)
            {
                SymbolTable.TryRemoveNullable(ref classType);
                if (null != classType && (classType.TypeKind == TypeKind.Delegate || classType.IsGenericType && SymbolTable.Instance.IsLegalGenericType(classType, true)))
                {
                    //如果是标记为合法的泛型类或委托类型的成员,则不用再进行类型检查
                }
                else
                {
                    var type = nodeType as INamedTypeSymbol;
                    SymbolTable.TryRemoveNullable(ref type);
                    if (null != type && !SymbolTable.Instance.IsCs2DslSymbol(type) && type.TypeKind != TypeKind.Delegate)
                    {
                        if (type.IsGenericType)
                        {
                            if (!SymbolTable.Instance.IsLegalParameterGenericType(type))
                            {
                                Logger.Instance.Log(node, "unsupported extern type '{0}' from member access !", SymbolTable.Instance.CalcFullNameAndTypeArguments(type));
                            }
                        }
                        else
                        {
                            if (SymbolTable.Instance.IsIllegalType(type))
                            {
                                Logger.Instance.Log(node, "unsupported extern type '{0}' from member access !", SymbolTable.Instance.CalcFullNameAndTypeArguments(type));
                            }
                        }
                    }
                }
            }
        }
Example #2
0
        internal static void CheckInvocation(SemanticModel model, IMethodSymbol sym, IList <ExpressionSyntax> args, IList <ArgDefaultValueInfo> nameOrDefValArgs, IList <IConversionOperation> argConversions, SyntaxNode node, IMethodSymbol callerSym)
        {
            if (!SymbolTable.EnableTranslationCheck)
            {
                return;
            }
            if (ClassInfo.HasAttribute(sym, "Cs2Dsl.DontCheckAttribute"))
            {
                return;
            }
            if (null != callerSym && ClassInfo.HasAttribute(callerSym, "Cs2Dsl.DontCheckAttribute"))
            {
                return;
            }
            if (null != callerSym && ClassInfo.HasAttribute(callerSym.ContainingType, "Cs2Dsl.DontCheckAttribute"))
            {
                return;
            }

            if (!SymbolTable.Instance.IsCs2DslSymbol(sym))
            {
                var ckey = ClassInfo.GetFullName(sym.ContainingType);
                var oper = null != node?model.GetOperationEx(node) as IInvocationOperation : null;

                var realType = null != oper && null != oper.Instance ? oper.Instance.Type : null;

                bool            isOverload = false;
                ClassSymbolInfo info;
                if (SymbolTable.Instance.ClassSymbols.TryGetValue(ckey, out info))
                {
                    info.SymbolOverloadFlags.TryGetValue(sym.Name, out isOverload);
                }

                string callerInfo = string.Empty;
                if (null != callerSym)
                {
                    var callerClass  = ClassInfo.GetFullName(callerSym.ContainingType);
                    var callerMethod = SymbolTable.Instance.NameCs2DslMangling(callerSym);
                    callerInfo = string.Format(" caller:{0}.{1}", callerClass, callerMethod);
                }

                if (sym.IsExtensionMethod && !SymbolTable.Instance.IsLegalExtension(sym.ContainingType))
                {
                    //不支持的语法
                    Logger.Instance.Log(node, "unsupported extern extension method {0}.{1} !{2}", ckey, sym.Name, string.IsNullOrEmpty(callerInfo) ? string.Empty : callerInfo);
                }
                else
                {
                    if (SymbolTable.Instance.IsIllegalMethod(sym))
                    {
                        Logger.Instance.Log(node, "unsupported extern method {0}.{1} !{2}", ckey, sym.Name, string.IsNullOrEmpty(callerInfo) ? string.Empty : callerInfo);
                    }
                }

                if (sym.ContainingType.TypeKind == TypeKind.Delegate ||
                    (null == realType || realType == sym.ContainingType) && sym.ContainingType.IsGenericType && SymbolTable.Instance.IsLegalGenericType(sym.ContainingType, true) ||
                    sym.IsGenericMethod && SymbolTable.Instance.IsLegalGenericMethod(sym))
                {
                    //如果是标记为合法的泛型类或委托类型的成员,则不用再进行类型检查
                }
                else
                {
                    int ix = 0;
                    foreach (var param in sym.Parameters)
                    {
                        ITypeSymbol _argType = null;
                        if (ix < args.Count)
                        {
                            _argType = null != args[ix] ? model.GetTypeInfoEx(args[ix]).Type : null;
                        }
                        else if (ix < args.Count + nameOrDefValArgs.Count)
                        {
                            _argType = nameOrDefValArgs[ix - args.Count].Type;
                        }
                        IConversionOperation argConv = null;
                        if (ix < argConversions.Count)
                        {
                            argConv = argConversions[ix];
                        }
                        ++ix;
                        INamedTypeSymbol argType = null;
                        if (null != _argType && (null == argConv || null == argConv.OperatorMethod))
                        {
                            argType = _argType as INamedTypeSymbol;
                        }
                        var paramType = param.Type as INamedTypeSymbol;
                        if (param.IsParams && isOverload)
                        {
                            Logger.Instance.Log(node, "extern overloaded method {0}.{1} parameter {2} is params, please check export api code !{3}", ckey, sym.Name, param.Name, string.IsNullOrEmpty(callerInfo) ? string.Empty : callerInfo);
                            continue;
                        }
                        if (null != paramType && paramType.TypeKind != TypeKind.Delegate)
                        {
                            bool isContainerIntf = paramType.Name == "IEnumerable" || paramType.Name == "ICollection" || paramType.Name == "IDictionary" || paramType.Name == "IList";
                            if (null != realType && SymbolTable.Instance.IsCs2DslSymbol(realType) && isContainerIntf &&
                                null != argType && (argType.IsGenericType || SymbolTable.Instance.IsCs2DslSymbol(argType)))
                            {
                                Logger.Instance.Log(node, "extern method {0}.{1} parameter {2} can't assign a script object to it !{3}", ckey, sym.Name, param.Name, string.IsNullOrEmpty(callerInfo) ? string.Empty : callerInfo);
                            }
                            else if (paramType.IsGenericType)
                            {
                                if (!SymbolTable.Instance.IsLegalParameterGenericType(paramType))
                                {
                                    Logger.Instance.Log(node, "extern method {0}.{1} parameter {2} is generic type, please replace with non generic type !{3}", ckey, sym.Name, param.Name, string.IsNullOrEmpty(callerInfo) ? string.Empty : callerInfo);
                                }
                            }
                            else
                            {
                                if (SymbolTable.Instance.IsIllegalType(paramType))
                                {
                                    Logger.Instance.Log(node, "extern method {0}.{1} parameter {2} is unsupported type, please replace with non generic type !{3}", ckey, sym.Name, param.Name, string.IsNullOrEmpty(callerInfo) ? string.Empty : callerInfo);
                                }
                            }
                        }
                    }
                    if (!sym.ReturnsVoid)
                    {
                        var type = sym.ReturnType as INamedTypeSymbol;
                        if (null != type && type.TypeKind != TypeKind.Delegate)
                        {
                            if (type.IsGenericType)
                            {
                                if (!SymbolTable.Instance.IsLegalParameterGenericType(type))
                                {
                                    Logger.Instance.Log(node, "extern method {0}.{1} return {2} is generic type, please replace with non generic type !{3}", ckey, sym.Name, type.Name, string.IsNullOrEmpty(callerInfo) ? string.Empty : callerInfo);
                                }
                            }
                            else
                            {
                                if (SymbolTable.Instance.IsIllegalType(type))
                                {
                                    Logger.Instance.Log(node, "extern method {0}.{1} return {2} is unsupported type, please replace with non generic type !{3}", ckey, sym.Name, type.Name, string.IsNullOrEmpty(callerInfo) ? string.Empty : callerInfo);
                                }
                            }
                        }
                    }
                }
            }
        }
Example #3
0
 internal bool IsIgnoredSymbol(ITypeSymbol sym)
 {
     return(m_IgnoredTypes.ContainsKey(ClassInfo.GetFullName(sym)));
 }
Example #4
0
        public override void VisitIdentifierName(IdentifierNameSyntax node)
        {
            string name = node.Identifier.Text;

            if (m_ClassInfoStack.Count > 0)
            {
                ClassInfo  classInfo  = m_ClassInfoStack.Peek();
                SymbolInfo symbolInfo = m_Model.GetSymbolInfo(node);
                var        sym        = symbolInfo.Symbol;
                if (null != sym)
                {
                    if (sym.Kind == SymbolKind.NamedType || sym.Kind == SymbolKind.Namespace)
                    {
                        string fullName = ClassInfo.GetFullName(sym);
                        CodeBuilder.Append(fullName);

                        if (sym.Kind == SymbolKind.NamedType)
                        {
                            var namedType = sym as INamedTypeSymbol;
                            AddReferenceAndTryDeriveGenericTypeInstance(classInfo, namedType);
                        }
                        return;
                    }
                    else if (sym.Kind == SymbolKind.Field || sym.Kind == SymbolKind.Property || sym.Kind == SymbolKind.Event)
                    {
                        if (IsNewObjMember(name))
                        {
                            CodeBuilder.AppendFormat("getinstance(newobj, \"{0}\")", name);
                            return;
                        }
                        if (sym.ContainingType == classInfo.SemanticInfo || sym.ContainingType == classInfo.SemanticInfo.OriginalDefinition || classInfo.IsInherit(sym.ContainingType))
                        {
                            if (sym.IsStatic)
                            {
                                CodeBuilder.AppendFormat("getstatic({0}, \"{1}\")", classInfo.Key, sym.Name);
                            }
                            else
                            {
                                CodeBuilder.AppendFormat("getinstance(this, \"{0}\")", sym.Name);
                            }
                            return;
                        }
                    }
                    else if (sym.Kind == SymbolKind.Method && (sym.ContainingType == classInfo.SemanticInfo || sym.ContainingType == classInfo.SemanticInfo.OriginalDefinition || classInfo.IsInherit(sym.ContainingType)))
                    {
                        var    msym         = sym as IMethodSymbol;
                        string manglingName = NameMangling(msym);
                        var    mi           = new MethodInfo();
                        mi.Init(msym, node);
                        if (node.Parent is InvocationExpressionSyntax)
                        {
                            if (sym.IsStatic)
                            {
                                CodeBuilder.AppendFormat("getstatic({0}, \"{1}\")", classInfo.Key, manglingName);
                            }
                            else
                            {
                                CodeBuilder.AppendFormat("getinstance(this, \"{0}\")", manglingName);
                            }
                        }
                        else
                        {
                            string className     = ClassInfo.GetFullName(msym.ContainingType);
                            string delegationKey = string.Format("{0}:{1}", className, manglingName);
                            string varName       = string.Format("__delegation_{0}", GetSourcePosForVar(node));

                            CodeBuilder.Append("(function(){ ");

                            string paramsString = string.Join(", ", mi.ParamNames.ToArray());
                            if (msym.IsStatic)
                            {
                                CodeBuilder.AppendFormat("builddelegation(\"{0}\", {1}, \"{2}\", {3}, {4}, {5}, {6});", paramsString, varName, delegationKey, className, manglingName, msym.ReturnsVoid ? "false" : "true", msym.IsStatic ? "true" : "false");
                            }
                            else
                            {
                                CodeBuilder.AppendFormat("builddelegation(\"{0}\", {1}, \"{2}\", {3}, {4}, {5}, {6});", paramsString, varName, delegationKey, "this", manglingName, msym.ReturnsVoid ? "false" : "true", msym.IsStatic ? "true" : "false");
                            }

                            CodeBuilder.Append(" })()");
                        }
                        return;
                    }
                }
                else
                {
                    if (IsNewObjMember(name))
                    {
                        CodeBuilder.AppendFormat("getinstance(newobj, \"{0}\")", name);
                        return;
                    }
                    ReportIllegalSymbol(node, symbolInfo);
                }
            }
            CodeBuilder.Append(name);
        }
Example #5
0
        private void Init(IMethodSymbol sym)
        {
            MethodSymbol = sym;
            TypeChecker.CheckInvocation(sym, CallerMethodSymbol, CallerSyntaxNode);

            Args.Clear();
            ArgConversions.Clear();
            ReturnArgs.Clear();
            GenericTypeArgs.Clear();

            ClassKey            = ClassInfo.GetFullName(sym.ContainingType);
            GenericClassKey     = ClassInfo.GetFullNameWithTypeParameters(sym.ContainingType);
            IsEnumClass         = sym.ContainingType.TypeKind == TypeKind.Enum || ClassKey == "System.Enum";
            IsExtensionMethod   = sym.IsExtensionMethod;
            IsBasicValueMethod  = SymbolTable.IsBasicValueMethod(sym);
            IsArrayStaticMethod = ClassKey == "System.Array" && sym.IsStatic;
            IsExternMethod      = !SymbolTable.Instance.IsCs2DslSymbol(sym);

            if ((ClassKey == "UnityEngine.GameObject" || ClassKey == "UnityEngine.Component") && (sym.Name.StartsWith("GetComponent") || sym.Name.StartsWith("AddComponent")))
            {
                IsComponentGetOrAdd = true;
            }

            NonGenericMethodSymbol      = null;
            PostPositionGenericTypeArgs = false;
            if (sym.IsGenericMethod)
            {
                bool existNonGenericVersion = !IsExternMethod;
                var  ctype = sym.ContainingType;
                var  syms  = ctype.GetMembers(sym.Name);
                if (null != syms)
                {
                    foreach (var isym in syms)
                    {
                        var msym = isym as IMethodSymbol;
                        if (null != msym && !msym.IsGenericMethod && msym.Parameters.Length == sym.Parameters.Length + sym.TypeParameters.Length)
                        {
                            existNonGenericVersion = true;
                            for (int i = 0; i < sym.TypeParameters.Length; ++i)
                            {
                                var psym = msym.Parameters[i];
                                if (psym.Type.Name != "Type")
                                {
                                    existNonGenericVersion = false;
                                    break;
                                }
                            }
                            for (int i = 0; i < sym.Parameters.Length; ++i)
                            {
                                var psym1 = msym.Parameters[i + sym.TypeParameters.Length];
                                var psym2 = sym.Parameters[i];
                                if (psym1.Type.Name != psym2.Type.Name && psym2.OriginalDefinition.Type.TypeKind != TypeKind.TypeParameter)
                                {
                                    existNonGenericVersion = false;
                                    break;
                                }
                            }
                            if (existNonGenericVersion)
                            {
                                NonGenericMethodSymbol      = msym;
                                PostPositionGenericTypeArgs = false;
                            }
                            else
                            {
                                existNonGenericVersion = true;
                                for (int i = 0; i < sym.Parameters.Length; ++i)
                                {
                                    var psym1 = msym.Parameters[i];
                                    var psym2 = sym.Parameters[i];
                                    if (psym1.Type.Name != psym2.Type.Name && psym2.OriginalDefinition.Type.TypeKind != TypeKind.TypeParameter)
                                    {
                                        existNonGenericVersion = false;
                                        break;
                                    }
                                }
                                for (int i = 0; i < sym.TypeParameters.Length; ++i)
                                {
                                    var psym = msym.Parameters[i + sym.Parameters.Length];
                                    if (psym.Type.Name != "Type")
                                    {
                                        existNonGenericVersion = false;
                                        break;
                                    }
                                }
                                if (existNonGenericVersion)
                                {
                                    NonGenericMethodSymbol      = msym;
                                    PostPositionGenericTypeArgs = true;
                                }
                            }
                            if (existNonGenericVersion)
                            {
                                break;
                            }
                        }
                    }
                }
                if (existNonGenericVersion)
                {
                    foreach (var arg in sym.TypeArguments)
                    {
                        GenericTypeArgs.Add(arg);
                    }
                }
            }

            ExternOverloadedMethodSignature = string.Empty;
            if (IsExternMethod)
            {
                var syms = sym.ContainingType.GetMembers(sym.Name);
                if (null != syms)
                {
                    int mcount = 0;
                    foreach (var isym in syms)
                    {
                        var msym = isym as IMethodSymbol;
                        var fn   = ClassInfo.GetFullName(msym.ContainingType);
                        if (null != msym && msym.IsStatic == sym.IsStatic && msym.DeclaredAccessibility == Accessibility.Public && !msym.IsImplicitlyDeclared && !msym.IsGenericMethod)
                        {
                            ++mcount;
                        }
                    }
                    if (mcount > 1)
                    {
                        ExternOverloadedMethodSignature = SymbolTable.CalcOverloadedMethodSignature(sym, NonGenericMethodSymbol);
                    }
                }
            }
        }