public static ParsedField GetParsedField(string line) { Scope scope; ParsedType type; string variableName; bool isConst; string valueToAssignTo; bool isVirtual; bool isOverride; bool isStatic; bool isNew; bool isAsync; ParsedMethod.GetLineInformation(line, out scope, out type, out variableName, out isConst, out isVirtual, out isOverride, out isStatic, out isNew, out isAsync, out valueToAssignTo); ParsedField parsedField = new ParsedField(); parsedField.Scope = scope; parsedField.Type = type; parsedField.Name = variableName; parsedField.IsConst = isConst; parsedField.IsStatic = isStatic; parsedField.ValueToAssignTo = valueToAssignTo; return(parsedField); }
private void CreateParsedMethod(int startIndex, int endIndex, bool trimContents) { // For now we'll assume that all properties are on // the same line. Eventually we may want to combine // all lines before the opening bracket // todo: add attributes: CurrentAttributes.Clear(); #region Get header information int lineIndexForHeader = 0; string headerLine = mCurrentBlock[lineIndexForHeader].Trim(); int numberOfParens = mCurrentBlock[lineIndexForHeader].CountOf('(') - mCurrentBlock[lineIndexForHeader].CountOf(')'); while (numberOfParens > 0) { lineIndexForHeader++; headerLine += " " + mCurrentBlock[lineIndexForHeader].Trim(); numberOfParens += mCurrentBlock[lineIndexForHeader].CountOf('(') - mCurrentBlock[lineIndexForHeader].CountOf(')'); } ParsedMethod parsedMethod = new ParsedMethod(); parsedMethod.FillHeaderInformation(headerLine); #endregion parsedMethod.StartIndex = startIndex; parsedMethod.EndIndex = endIndex; parsedMethod.FillArgumentList(parsedMethod, mCurrentBlock, 0, true); // Fill generic restrictions after getting all arguments parsedMethod.FillGenericRestrictions(headerLine); parsedMethod.FillBaseCall(mCurrentBlock); StringBuilder methodContents = new StringBuilder(); bool hasGetter; bool hasSetter; bool hasAutomaticGetter; bool hasAutomaticSetter; FillGettersAndSetters(methodContents, methodContents, false, trimContents, out hasGetter, out hasSetter, out hasAutomaticGetter, out hasAutomaticSetter); parsedMethod.MethodContents = methodContents.ToString(); parsedMethod.StoreOffOldName(); mParsedMethods.Add(parsedMethod); }
internal void FillBaseCall(List <string> currentBlock) { int lineOn = 1; string baseCall = ""; if (currentBlock.Count == 1) { return; } while (true) { // We need to trim here because we may not have // trimmed the content already if (lineOn >= currentBlock.Count) { break; } string line = currentBlock[lineOn].Trim(); if (line.StartsWith("{")) { break; } else if ((line.Contains("base") || line.Contains("this")) && !line.EndsWith(";")) { baseCall += line; } lineOn++; } if (baseCall != "") { BaseCall = new ParsedMethod(); if (baseCall.StartsWith(":")) { baseCall = baseCall.Substring(1).Trim(); } BaseCall.FillHeaderInformation(baseCall); BaseCall.FillArgumentList(BaseCall, currentBlock, lineOn - 1, false); } }
public ParsedMethod Clone() { ParsedMethod parsedMethod = (ParsedMethod)this.MemberwiseClone(); parsedMethod.Type = Type.Clone(); parsedMethod.ArgumentList = new List <ParsedField>(); parsedMethod.GenericTypes = new List <ParsedType>(); foreach (ParsedField argument in ArgumentList) { parsedMethod.ArgumentList.Add(argument.Clone()); } foreach (ParsedType genericType in GenericTypes) { parsedMethod.GenericTypes.Add(genericType.Clone()); } return(parsedMethod); }
public ParsedMethod GetMethod(string methodName) { foreach (ParsedMethod parsedMethod in mParsedMethods) { if (parsedMethod.Name == methodName) { return(parsedMethod); } } foreach (ParsedClass parentClass in mParentParsedClasses) { ParsedMethod parsedMethods = parentClass.GetMethod(methodName); if (parsedMethods != null) { return(parsedMethods); } } return(null); }
internal void FillArgumentList(ParsedMethod parsedMethod, List <string> currentBlock, int lineIndex, bool requireTypes) { int wordIndex = 0; int parenthesisDeep = 0; bool hasFoundClosedParenthesis = false; ParsedField argumentToAddTo = null; while (!hasFoundClosedParenthesis) { string line = currentBlock[lineIndex]; wordIndex = 0; string currentType = null; while (true) { string word = ParsedClass.GetWord(line, ref wordIndex); if (word == "(") { if (argumentToAddTo != null) { argumentToAddTo.Name += word; } parenthesisDeep++; } else if (word == ")") { parenthesisDeep--; if (parenthesisDeep == 0) { hasFoundClosedParenthesis = true; break; } else if (argumentToAddTo != null) { argumentToAddTo.Name += word; } } else if (word == "") { lineIndex++; break; } else if (parenthesisDeep == 0) { continue; } else if (word == ",") { argumentToAddTo = null; continue; } else if (currentType == null && requireTypes) { currentType = word; } else { ParsedField parsedField = new ParsedField(Scope.Public, currentType, word); currentType = null; parsedMethod.ArgumentList.Add(parsedField); argumentToAddTo = parsedField; } } } }
private void CreateParsedMethod(int startIndex, int endIndex, bool trimContents) { // For now we'll assume that all properties are on // the same line. Eventually we may want to combine // all lines before the opening bracket // todo: add attributes: CurrentAttributes.Clear(); #region Get header information int lineIndexForHeader = 0; string headerLine = mCurrentBlock[lineIndexForHeader].Trim() ; int numberOfParens = mCurrentBlock[lineIndexForHeader].CountOf('(') - mCurrentBlock[lineIndexForHeader].CountOf(')'); while (numberOfParens > 0) { lineIndexForHeader++; headerLine += " " + mCurrentBlock[lineIndexForHeader].Trim(); numberOfParens += mCurrentBlock[lineIndexForHeader].CountOf('(') - mCurrentBlock[lineIndexForHeader].CountOf(')'); } ParsedMethod parsedMethod = new ParsedMethod(); parsedMethod.FillHeaderInformation(headerLine); #endregion parsedMethod.StartIndex = startIndex; parsedMethod.EndIndex = endIndex; parsedMethod.FillArgumentList(parsedMethod, mCurrentBlock, 0, true); // Fill generic restrictions after getting all arguments parsedMethod.FillGenericRestrictions(headerLine); parsedMethod.FillBaseCall(mCurrentBlock); StringBuilder methodContents = new StringBuilder(); bool hasGetter; bool hasSetter; bool hasAutomaticGetter; bool hasAutomaticSetter; FillGettersAndSetters(methodContents, methodContents, false, trimContents, out hasGetter, out hasSetter, out hasAutomaticGetter, out hasAutomaticSetter); parsedMethod.MethodContents = methodContents.ToString(); parsedMethod.StoreOffOldName(); mParsedMethods.Add(parsedMethod); }
private void CreateParsedProperty() { // For now we'll assume that all properties are on // the same line. Eventually we may want to combine // all lines before the opening bracket string headerLine = mCurrentBlock[0]; #region Get header information Scope scope; ParsedType type; string variableName; bool isConst; // will always be false for properties string valueToAssignTo; bool isVirtual; bool isOverride; bool isStatic; bool isNew; bool isAsync; ParsedMethod.GetLineInformation(headerLine, out scope, out type, out variableName, out isConst, out isVirtual, out isOverride, out isStatic, out isNew, out isAsync, out valueToAssignTo); ParsedProperty parsedProperty = new ParsedProperty(); parsedProperty.Scope = scope; parsedProperty.Type = type; parsedProperty.Name = variableName; parsedProperty.IsVirtual = isVirtual; parsedProperty.IsStatic = isStatic; #endregion StringBuilder getterLines = new StringBuilder(); StringBuilder setterLines = new StringBuilder(); bool hasGetter; bool hasSetter; bool hasAutomaticGetter; bool hasAutomaticSetter; FillGettersAndSetters(getterLines, setterLines, true, false, out hasGetter, out hasSetter, out hasAutomaticGetter, out hasAutomaticSetter); parsedProperty.HasAutomaticGetter = hasAutomaticGetter; parsedProperty.HasAutomaticSetter = hasAutomaticSetter; if (hasGetter) { parsedProperty.GetContents = getterLines.ToString(); } else { parsedProperty.GetContents = null; } if (hasSetter) { parsedProperty.SetContents = setterLines.ToString(); } else { parsedProperty.SetContents = null; } parsedProperty.Attributes.AddRange(CurrentAttributes); mParsedProperties.Add(parsedProperty); }
void ParseContents(string classContents, bool trim) { int index = 0; int bracketsDeep = 0; PreProcessorDefineParser.Clear(); string remainderOfLine = null; while (true) { string line = ""; string untrimmedLine = ""; if (remainderOfLine == null) { untrimmedLine = GetLine(classContents, ref index); line = untrimmedLine.Trim(); } else { line = remainderOfLine; } bool isComment = line.Trim().StartsWith("//"); remainderOfLine = null; #region If it's empty, continue or end depending on how far we are in the file if (line == "") { if (index != classContents.Length) { continue; } else { break; } } #endregion #region It's a define code like #if or #elif or #else else if (line.StartsWith("#if ") || line.StartsWith("#endif") || line.StartsWith("#elif") || line.StartsWith("#else")) { PreProcessorDefineParser.ParseLine(line); } #endregion else if (PreProcessorDefineParser.ShouldLineBeSkipped(mAddedDefines) || isComment) { continue; } #region It's just an empty line ( "\r" ) else if (line == "\r") { // do nothing, continue } #endregion #region It's an open bracket ( "{" ) else if (line.StartsWith("{")) { bracketsDeep++; if (mCurrentBlock.Count != 0) { if (trim) { AddToCurrentBlock(line, index); } else { AddToCurrentBlock(untrimmedLine, index); } } if (line != "{") { remainderOfLine = line.Substring(1); } } #endregion #region It's a close bracket ( "}" ) else if (line.StartsWith("}")) { bracketsDeep--; if (mCurrentBlock.Count != 0) { if (trim) { AddToCurrentBlock(line, index); } else { AddToCurrentBlock(untrimmedLine, index); } } if (bracketsDeep == 1) { ProcessCurrentBlock(index, trim); } if (line != "}") { remainderOfLine = line.Substring(1); } } #endregion #region If it's a field else if (bracketsDeep == 1 && line.EndsWith(";") && // C# 6 introduces assigning values like public float Something { get; set; } = 3; !line.Contains("{")) { if (line.Contains('(') && line.EndsWith(");") && !line.Contains("=")) { // likely a single-line method in an interface // void ClearRelationships(); if (trim) { AddToCurrentBlock(line, index); } else { AddToCurrentBlock(untrimmedLine, index); } ProcessCurrentBlock(index, trim); } else { ParseField(line); } } #endregion #region Attributes else if (bracketsDeep == 1 && line.StartsWith("[") && line.EndsWith("]")) { AddAttribute(line); } #endregion #region If there is a bracket inside a line "}" else if (bracketsDeep == 1 && NumberOfValid('{', line) != 0) { // Could be a single-liner // let's parse it as a property if (trim) { AddToCurrentBlock(line, index); } else { AddToCurrentBlock(untrimmedLine, index); } if (line.Contains('}')) { ProcessCurrentBlock(index, trim); } else { bracketsDeep++; } } #endregion else if (mCurrentBlock.Count == 0 && line.StartsWith("[") && line.EndsWith("]")) { // It's an attribute like [XmlIgnore]. Don't do anything with this for now } else if (line.StartsWith("#region ") || line.StartsWith("#endregion")) { // do nothing } #region Else, save off this line - it may be part of a method or property else { bool containsCloseBracket = false; if (bracketsDeep > 0) { if (trim) { AddToCurrentBlock(line, index); } else { AddToCurrentBlock(untrimmedLine, index); } } // The following methods will properly handle { and } inside quotes, like // string classFormat = "Level{0}"; if (NumberOfValid('{', line) > 0) { bracketsDeep++; } if (NumberOfValid('}', line) > 0) { bracketsDeep--; containsCloseBracket = true; } // I think we want to check this *before* increasing the bracketsDeep value //if (bracketsDeep > 0) //{ // if (trim) // { // AddToCurrentBlock(line, index); // } // else // { // AddToCurrentBlock(untrimmedLine, index); // } //} if (containsCloseBracket) { if (bracketsDeep == 1) { ProcessCurrentBlock(index, trim); } } } #endregion } // Mark any overloaded methods as such List <string> methodNamesSoFar = new List <string>(); for (int i = 0; i < mParsedMethods.Count - 1; i++) { ParsedMethod method = mParsedMethods[i]; for (int j = i + 1; j < mParsedMethods.Count; j++) { ParsedMethod otherMethod = mParsedMethods[j]; // Normally we use the Method.ToString to identify methods, but here we're looking for overloads, so we'll use name // ...but is this okay? Or do we want to use ToString to get exact matches? if (method.Name == otherMethod.Name) { method.IsOverload = true; otherMethod.IsOverload = true; } } } }
internal void FillArgumentList(ParsedMethod parsedMethod, List<string> currentBlock, int lineIndex, bool requireTypes) { int wordIndex = 0; int parenthesisDeep = 0; bool hasFoundClosedParenthesis = false; ParsedField argumentToAddTo = null; while (!hasFoundClosedParenthesis) { string line = currentBlock[lineIndex]; wordIndex = 0; string currentType = null; while (true) { string word = ParsedClass.GetWord(line, ref wordIndex); if (word == "(") { if (argumentToAddTo != null) { argumentToAddTo.Name += word; } parenthesisDeep++; } else if (word == ")") { parenthesisDeep--; if (parenthesisDeep == 0) { hasFoundClosedParenthesis = true; break; } else if (argumentToAddTo != null) { argumentToAddTo.Name += word; } } else if (word == "") { lineIndex++; break; } else if (parenthesisDeep == 0) { continue; } else if (word == ",") { argumentToAddTo = null; continue; } else if (currentType == null && requireTypes) { currentType = word; } else { ParsedField parsedField = new ParsedField(Scope.Public, currentType, word); currentType = null; parsedMethod.ArgumentList.Add(parsedField); argumentToAddTo = parsedField; } } } }
internal void FillBaseCall(List<string> currentBlock) { int lineOn = 1; string baseCall = ""; if (currentBlock.Count == 1) { return; } while (true) { // We need to trim here because we may not have // trimmed the content already if (lineOn >= currentBlock.Count) { break; } string line = currentBlock[lineOn].Trim(); if (line.StartsWith("{")) { break; } else if( (line.Contains("base") || line.Contains("this")) && !line.EndsWith(";") ) { baseCall += line; } lineOn++; } if (baseCall != "") { BaseCall = new ParsedMethod(); if (baseCall.StartsWith(":")) { baseCall = baseCall.Substring(1).Trim(); } BaseCall.FillHeaderInformation(baseCall); BaseCall.FillArgumentList(BaseCall, currentBlock, lineOn - 1, false); } }
/// <summary> /// Returns the start and end index in the argument fileContents of the entire method including the header of the method /// and the opening/closing brackets. /// </summary> /// <param name="parsedMethod">The parsed method.</param> /// <param name="fileContents">The contents of the entire file.</param> /// <param name="startIndex">The found startIndex.</param> /// <param name="endIndex">The found endIndex which includes the closing bracket.</param> public static void GetStartAndEndIndexForMethod(ParsedMethod parsedMethod, string fileContents, out int startIndex, out int endIndex) { string name = parsedMethod.Name; GetStartAndEndIndexForMethod(fileContents, name, out startIndex, out endIndex); }