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)); } } } } } }
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); } } } } } } }
internal bool IsIgnoredSymbol(ITypeSymbol sym) { return(m_IgnoredTypes.ContainsKey(ClassInfo.GetFullName(sym))); }
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); }
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); } } } }