public override SyntaxNode VisitMemberAccessExpression(MemberAccessExpressionSyntax node) { var esym = m_Model.GetSymbolInfo(node).Symbol as IEventSymbol; var psym = m_Model.GetSymbolInfo(node).Symbol as IPropertySymbol; var fsym = m_Model.GetSymbolInfo(node).Symbol as IFieldSymbol; var msym = m_Model.GetSymbolInfo(node).Symbol as IMethodSymbol; var oper = m_Model.GetOperation(node); SyntaxNode newNode = null; var name = node.Expression as IdentifierNameSyntax; if (null != name) { var text = name.Identifier.Text; foreach (var ns in SymbolTable.Instance.Namespaces) { if (ns == text || ns.Contains("." + text + ".") || ns.EndsWith("." + text)) { newNode = SyntaxFactory.IdentifierName(node.Name.ToString()).WithLeadingTrivia(node.GetLeadingTrivia()).WithTrailingTrivia(node.GetTrailingTrivia()); } } } if (null == newNode) { newNode = base.VisitMemberAccessExpression(node); } bool isExtern = false; INamedTypeSymbol classType = null; if (null != esym && SymbolTable.Instance.IsExternSymbol(esym)) { isExtern = true; classType = esym.ContainingType; newNode = ReportAndAttachError(newNode, string.Format("[Cs2LuaRewriter] Unsupported extern event !")); } if (null != psym && SymbolTable.Instance.IsExternSymbol(psym)) { isExtern = true; classType = psym.ContainingType; if (SymbolTable.Instance.IsIllegalProperty(psym)) { newNode = ReportAndAttachError(newNode, string.Format("[Cs2LuaRewriter] Unsupported extern property !")); } } if (null != fsym && SymbolTable.Instance.IsExternSymbol(fsym)) { isExtern = true; classType = fsym.ContainingType; if (SymbolTable.Instance.IsIllegalField(fsym)) { newNode = ReportAndAttachError(newNode, string.Format("[Cs2LuaRewriter] Unsupported extern field !")); } } if (null != msym && !(node.Parent is InvocationExpressionSyntax) && SymbolTable.Instance.IsExternSymbol(msym.ContainingType)) { if (SymbolTable.Instance.IsIllegalMethod(msym)) { newNode = ReportAndAttachError(newNode, "[Cs2LuaRewriter] Unsupported extern method !"); } } if (isExtern && null != oper) { bool legal = true; SymbolTable.TryRemoveNullable(ref classType); if (null != classType && (classType.TypeKind == TypeKind.Delegate || classType.IsGenericType && SymbolTable.Instance.IsLegalGenericType(classType, true))) { //如果是标记为合法的泛型类或委托类型的成员,则不用再进行类型检查 } else { var type = oper.Type as INamedTypeSymbol; SymbolTable.TryRemoveNullable(ref type); if (null != type && SymbolTable.Instance.IsExternSymbol(type) && type.TypeKind != TypeKind.Delegate) { if (type.IsGenericType) { if (!SymbolTable.Instance.IsLegalParameterGenericType(type)) { legal = false; } } else { if (SymbolTable.Instance.IsIllegalType(type)) { legal = false; } } } } if (!legal) { newNode = ReportAndAttachError(newNode, string.Format("[Cs2LuaRewriter] Unsupported extern type from member access !")); } } return(newNode); }
public override SyntaxNode VisitInvocationExpression(InvocationExpressionSyntax node) { var sym = m_Model.GetSymbolInfo(node).Symbol as IMethodSymbol; var newNode = base.VisitInvocationExpression(node); if (null != sym && SymbolTable.Instance.IsExternSymbol(sym)) { var ckey = SymbolTable.CalcFullNameWithTypeParameters(sym.ContainingType, true); var oper = null != node?m_Model.GetOperation(node) as IInvocationExpression : null; var realType = null != oper && null != oper.Instance ? oper.Instance.Type : null; if (sym.IsExtensionMethod && !SymbolTable.Instance.IsLegalExtension(sym.ContainingType)) { //不支持的语法 newNode = ReportAndAttachError(newNode, "[Cs2LuaRewriter] Unsupported extension method !"); } else { if (SymbolTable.Instance.IsIllegalMethod(sym)) { newNode = ReportAndAttachError(newNode, "[Cs2LuaRewriter] Unsupported extern method !"); } } bool legal = true; 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 { List <ExpressionSyntax> args; List <ArgDefaultValueInfo> defArgs; List <IConversionExpression> argConversions; ExtractInvocationInfo(sym, node.ArgumentList, out args, out defArgs, out argConversions); int ix = 0; foreach (var param in sym.Parameters) { IOperation argOper = null; if (ix < args.Count) { argOper = null != args[ix] ? m_Model.GetOperation(args[ix]) : null; } else if (ix < args.Count + defArgs.Count) { argOper = defArgs[ix - args.Count].OperOrSym as IOperation; } IConversionExpression argConv = null; if (ix < argConversions.Count) { argConv = argConversions[ix]; } ++ix; INamedTypeSymbol argType = null; if (null != argOper && (null == argConv || !argConv.UsesOperatorMethod)) { argType = argOper.Type as INamedTypeSymbol; } var paramType = param.Type as INamedTypeSymbol; 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.IsExternSymbol(realType) && isContainerIntf && null != argType && (argType.IsGenericType || !SymbolTable.Instance.IsExternSymbol(argType))) { legal = false; } else if (paramType.IsGenericType) { if (!SymbolTable.Instance.IsLegalParameterGenericType(paramType)) { legal = false; } } else { if (SymbolTable.Instance.IsIllegalType(paramType)) { legal = false; } } } } if (!sym.ReturnsVoid) { var type = sym.ReturnType as INamedTypeSymbol; if (null != type && type.TypeKind != TypeKind.Delegate) { if (type.IsGenericType) { if (!SymbolTable.Instance.IsLegalParameterGenericType(type)) { legal = false; } } else { if (SymbolTable.Instance.IsIllegalType(type)) { legal = false; } } } } } if (!legal) { newNode = ReportAndAttachError(newNode, string.Format("[Cs2LuaRewriter] Unsupported extern type from invocation's return or params !")); } } return(newNode); }