private void ParseClass(AccessLevel accessLevel, bool isStatic) { Token classKeyword = _lexer.Eat(TokenType.ClassKeyword); Token name = _lexer.Eat(TokenType.Identifer); if (accessLevel != AccessLevel.Public) { accessLevel = AnalysisAccessLevel(name.Content); } Token colon = null, inheritanceToken = null; string inheritanceName = "object"; if (_lexer.Match(":")) { colon = _lexer.Eat(TokenType.Colon); inheritanceToken = _lexer.Eat(TokenType.Identifer); inheritanceName = inheritanceToken.Content; } ClassDefinition classDefinition = new ClassDefinition(classKeyword, name, colon, inheritanceToken, inheritanceName, _endNameSpace, accessLevel, isStatic); _endNameSpace.AddStructure(classDefinition); FilesDefinitions[_lexer.FileIndex].Add(classDefinition); _parsingStructure = classDefinition; classDefinition.AddFunction(new FunctionDefinition(classDefinition, ".ctor", classDefinition.AccessLevel, false)); classDefinition.AddFunction(new FunctionDefinition(classDefinition, ".cctor", classDefinition.AccessLevel, true)); ChunkNode chunk = ParseChunk(s_cusDefinitionOrder, out Token openBrace, out Token closeBrace); classDefinition.SetBraces(openBrace, closeBrace); foreach (SyntaxNode analysisNode in chunk.Nodes) { if (analysisNode.NodeType == NodeType.Assign) { classDefinition.GetFunctionDefinition(".ctor").ChunkNode.AddFirstNode(analysisNode); } classDefinition.AddField((DefineVariableNode)analysisNode); } _parsingStructure = null; }
public override void ProcessClass(Type classType, ClassDefinition classDef) { MethodInfo[] remoteMethods = remoteType.GetMethods(); bool isServer = !classType.IsSubclassOf(typeof(ClientScope)); // create and setup writer ClassDefinition fakeRemoteClass = new ClassDefinition(string.Format("Remote{0}", remoteType.Name)); { fakeRemoteClass.imports.Add("System.Collections.Generic"); fakeRemoteClass.imports.Add("UnityEngine.Networking"); // add interface sender field fakeRemoteClass.AddField("_netSender", "INetworkSender", false); // add constructor method MethodDefinition ctor = new MethodDefinition(fakeRemoteClass.Name); ctor.IsConstructor = true; ctor.parameters.Add(new ParameterDefinition("netSender", "INetworkSender")); fakeRemoteClass.methods.Add(ctor); // assign it in the body ctor.instructions.AddInstruction("_netSender = netSender;"); } // find remote methods with "Signal" attribute; the SEND methods bool didCreateAnySendMethods = false; foreach (MethodInfo remoteMethod in remoteMethods) { if (ReflectionUtility.ContainsAttribute <Signal>(remoteMethod)) { // create send remote method MethodDefinition fakeMethodDef = CreateSendMethod(remoteMethod); // if method call wasn't found, mark it invalid if (fakeMethodDef == null) { classDef.IsInvalid = true; continue; } // otherwise add it to the list of methods in the inner remote class fakeRemoteClass.methods.Add(fakeMethodDef); // flag that send methods were created to allow the class to be created in a future check didCreateAnySendMethods = true; } } // find local methods with "Signal" attribute; the RECEIVE methods foreach (MethodInfo localMethod in classType.GetMethods()) { if (ReflectionUtility.ContainsAttribute <Signal>(localMethod)) { // create send remote method MethodDefinition localMethodDef = CreateReceiveMethod(localMethod); // if method call wasn't found, mark it invalid if (localMethodDef == null) { classDef.IsInvalid = true; } // otherwise add it to the lsit of methods within the partial class else { classDef.methods.Add(localMethodDef); } } } // add SEND-specific code - ONLY if there's any any send methods generated earlier if (didCreateAnySendMethods) { classDef.classes.Add(fakeRemoteClass); if (isServer) { string peerTypeName = classType.BaseType.GetGenericArguments()[0].FullName; classDef.AddField("_Remote", fakeRemoteClass.Name, false); // send method (single-peer) MethodDefinition sendPeerMethod = new MethodDefinition("SendToPeer"); sendPeerMethod.ReturnType = fakeRemoteClass.Name; sendPeerMethod.parameters.Add(new ParameterDefinition("targetPeer", peerTypeName)); sendPeerMethod.instructions.AddInlineIfCheck("_Remote == null", string.Format("_Remote = new {0}(this);", fakeRemoteClass.Name)); sendPeerMethod.instructions.AddInstruction("TargetPeer = targetPeer;"); sendPeerMethod.instructions.AddInstruction("return _Remote;"); classDef.methods.Add(sendPeerMethod); // reply method (single-peer - last sender) sendPeerMethod = new MethodDefinition("ReplyToPeer"); sendPeerMethod.ReturnType = fakeRemoteClass.Name; sendPeerMethod.instructions.AddInlineIfCheck("_Remote == null", string.Format("_Remote = new {0}(this);", fakeRemoteClass.Name)); sendPeerMethod.instructions.AddInstruction("TargetPeer = SenderPeer;"); sendPeerMethod.instructions.AddInstruction("return _Remote;"); classDef.methods.Add(sendPeerMethod); // send method (multi-peer) sendPeerMethod = new MethodDefinition("SendToPeers"); sendPeerMethod.ReturnType = fakeRemoteClass.Name; sendPeerMethod.parameters.Add(new ParameterDefinition("targetPeerGroup", string.Format("IEnumerable<{0}>", peerTypeName))); sendPeerMethod.instructions.AddInlineIfCheck("_Remote == null", string.Format("_Remote = new {0}(this);", fakeRemoteClass.Name)); sendPeerMethod.instructions.AddInstruction("TargetPeerGroup = targetPeerGroup;"); sendPeerMethod.instructions.AddInstruction("return _Remote;"); classDef.methods.Add(sendPeerMethod); } else { // add the 'Server' property by that type classDef.AddField("_Remote", fakeRemoteClass.Name, false); var prop = classDef.AddProperty("SendToServer", fakeRemoteClass.Name); prop.getterBody = new MethodBodyDefinition(); prop.getterBody.AddInlineIfCheck("_Remote == null", string.Format("_Remote = new {0}(this);", fakeRemoteClass.Name)); prop.getterBody.AddInstruction("return _Remote;"); } } }