public static string GetGameObjectName(IBuffer buffer) { var start = ourGameObjectNameSearcher.Find(buffer, 0, buffer.Length); if (start < 0) { return(null); } var eol = ourEndLineSearcher.Find(buffer, start, buffer.Length); if (eol < 0) { eol = ourEndLine2Searcher.Find(buffer, start, buffer.Length); } if (eol < 0) { return(null); } var nameBuffer = ProjectedBuffer.Create(buffer, new TextRange(start, eol + 1)); var lexer = new YamlLexer(nameBuffer, false, false); var parser = new YamlParser(lexer.ToCachingLexer()); var document = parser.ParseDocument(); return((document.Body.BlockNode as IBlockMappingNode)?.Entries.FirstOrDefault()?.Content.Value .GetPlainScalarText()); }
public IChameleonNode ReSync(CachingLexer cachingLexer, TreeTextRange changedRange, int insertedTextLen) { var currentStartOffset = GetTreeStartOffset(); var currentLength = GetTextLength(); Assertion.Assert( changedRange.StartOffset >= currentStartOffset && changedRange.EndOffset <= currentStartOffset + currentLength, "changedRange.StartOffset >= currentStartOffset && changedRange.EndOffset <= (currentStartOffset+currentLength)"); var newLength = currentLength - changedRange.Length + insertedTextLen; // Can we resync from the start point? if (!cachingLexer.FindTokenAt(currentStartOffset.Offset) || cachingLexer.TokenStart != currentStartOffset.Offset || !IsAtValidStartToken(cachingLexer)) { return(null); } // Try to find a valid end point TokenNodeType tokenType; var calculatedNewLength = 0; while ((tokenType = cachingLexer.TokenType) != null && (calculatedNewLength += cachingLexer.TokenEnd - cachingLexer.TokenStart) < newLength) { // We shouldn't encounter these until the end of the changed range if (tokenType == YamlTokenType.DOCUMENT_END || tokenType == YamlTokenType.DIRECTIVES_END) { return(null); } cachingLexer.Advance(); } if (calculatedNewLength != newLength || !IsAtValidEndToken(cachingLexer)) { return(null); } // TODO: Should this be synchronised? // The C# implementation isn't... if (!myOpened) { var buffer = ProjectedBuffer.Create(cachingLexer.Buffer, new TextRange(currentStartOffset.Offset, currentStartOffset.Offset + newLength)); var closedChameleon = new ClosedChameleonElement(YamlTokenType.CHAMELEON, buffer, TreeOffset.Zero, new TreeOffset(buffer.Length)); return(new ChameleonDocumentBody(closedChameleon)); } var projectedLexer = new ProjectedLexer(cachingLexer, new TextRange(currentStartOffset.Offset, currentStartOffset.Offset + newLength)); var parser = (IYamlParser)Language.LanguageService().CreateParser(projectedLexer, GetPsiModule(), GetSourceFile()); var openedChameleon = parser.ParseDocumentBody(); return(new ChameleonDocumentBody(openedChameleon)); }
/// <summary> /// Tries to create a lexer for a code behind file. /// </summary> /// <param name="baseLexer">The base T4 lexer.</param> /// <returns>A C# lexer for the current code block, or <c>null</c> if none could be created.</returns> public ILexer TryCreateCodeBehindLexer(ILexer baseLexer) { if (baseLexer.TokenType == T4TokenNodeTypes.Code) { LanguageService service = _codeBehindLanguage.LanguageService(); if (service != null) { var buffer = new ProjectedBuffer(_mixedLexer.Buffer, new TextRange(_mixedLexer.PrimaryLexer.TokenStart, _mixedLexer.PrimaryLexer.AdvanceWhile(T4TokenNodeTypes.Code))); ILexer lexer = service.GetPrimaryLexerFactory().CreateLexer(buffer); lexer.Start(); return lexer; } } return null; }
/// <summary> /// Tries to create a lexer for a code behind file. /// </summary> /// <param name="baseLexer">The base T4 lexer.</param> /// <returns>A C# lexer for the current code block, or <c>null</c> if none could be created.</returns> public ILexer TryCreateCodeBehindLexer(ILexer baseLexer) { if (baseLexer.TokenType == T4TokenNodeTypes.Code) { LanguageService service = _codeBehindLanguage.LanguageService(); if (service != null) { var buffer = new ProjectedBuffer(_mixedLexer.Buffer, new TextRange(_mixedLexer.PrimaryLexer.TokenStart, _mixedLexer.PrimaryLexer.AdvanceWhile(T4TokenNodeTypes.Code))); ILexer lexer = service.GetPrimaryLexerFactory().CreateLexer(buffer); lexer.Start(); return(lexer); } } return(null); }
public (IEnumerable <CppFileLocation> includeLocations, Dictionary <string, string> defines) GetProgramInfo(CppFileLocation cppFileLocation) { // PSI is not commited here // TODO: cpp global cache should calculate cache only when PSI for file with cpp injects is committed. var sourceFile = cppFileLocation.GetRandomSourceFile(mySolution); var range = cppFileLocation.RootRange; Assertion.Assert(range.IsValid, "range.IsValid"); var buffer = sourceFile.Document.Buffer; var type = GetShaderProgramType(buffer, range.StartOffset); var defines = GetDefinedMacroses(ProjectedBuffer.Create(buffer, range), out var isSurface); var includes = GetIncludes(sourceFile, type, isSurface); return(includes, defines); }
public static IHierarchyReference GetReferenceBySearcher(IPsiSourceFile assetSourceFile, IBuffer assetDocumentBuffer, StringSearcher searcher) { var start = searcher.Find(assetDocumentBuffer, 0, assetDocumentBuffer.Length); if (start < 0) { return(null); } var end = ourBracketSearcher.Find(assetDocumentBuffer, start, assetDocumentBuffer.Length); if (end < 0) { return(null); } var buffer = ProjectedBuffer.Create(assetDocumentBuffer, new TextRange(start, end + 1)); var lexer = new YamlLexer(buffer, false, false); var parser = new YamlParser(lexer.ToCachingLexer()); var document = parser.ParseDocument(); return((document.Body.BlockNode as IBlockMappingNode)?.Entries.FirstOrDefault()?.Content.Value.ToHierarchyReference(assetSourceFile)); }
public static void ExtractSimpleAndReferenceValues(IBuffer buffer, Dictionary <string, string> simpleValues, Dictionary <string, FileID> referenceValues) { // special field for accessing anchor id simpleValues["&anchor"] = GetAnchorFromBuffer(buffer); var lexer = new YamlLexer(buffer, true, false); lexer.Start(); TokenNodeType currentToken; bool noColon = true; while ((currentToken = lexer.TokenType) != null) { if (noColon) { if (currentToken == YamlTokenType.COLON) { noColon = false; } if (currentToken == YamlTokenType.NS_PLAIN_ONE_LINE_OUT) { var key = buffer.GetText(new TextRange(lexer.TokenStart, lexer.TokenEnd)); // special filed for checking stripped documents if (key.Equals("stripped")) { simpleValues["stripped"] = "1"; } } } if (currentToken == YamlTokenType.INDENT) { lexer.Advance(); currentToken = lexer.TokenType; if (currentToken == YamlTokenType.NS_PLAIN_ONE_LINE_IN) { var key = buffer.GetText(new TextRange(lexer.TokenStart, lexer.TokenEnd)); lexer.Advance(); SkipWhitespace(lexer); currentToken = lexer.TokenType; if (currentToken == YamlTokenType.COLON) { lexer.Advance(); SkipWhitespace(lexer); currentToken = lexer.TokenType; if (currentToken == YamlTokenType.LBRACE) { lexer.Advance(); var result = GetFileIdInner(buffer, lexer); if (result != null) { referenceValues[key] = result; } } else if (YamlTokenType.CHAMELEON_BLOCK_MAPPING_ENTRY_CONTENT_WITH_ANY_INDENT.Equals(currentToken)) { // sometimes, FileId is multiline var result = GetFileId(ProjectedBuffer.Create(buffer, new TextRange(lexer.TokenStart, lexer.TokenEnd))); if (result != null) { referenceValues[key] = result; } } else { var result = GetPrimitiveValue(buffer, lexer); if (result != null) { simpleValues[key] = result; } } } } else { FindNextIndent(lexer); } } else { lexer.Advance(); } } }
public IEnumerable <CppFileLocation> GetIncludes(CppFileLocation cppFileLocation) { // PSI is not commited here // TODO: cpp global cache should calculate cache only when PSI for file with cpp injects is committed. var sourceFile = cppFileLocation.GetRandomSourceFile(mySolution); var range = cppFileLocation.RootRange; Assertion.Assert(range.IsValid, "range.IsValid"); var buffer = sourceFile.Document.Buffer; var type = GetShaderProgramType(buffer, range.StartOffset); var includeType = GetIncludeProgramType(type); yield return(new CppFileLocation(myCppExternalModule, mySolution.SolutionDirectory.Combine(Utils.ShaderConfigFile))); if (includeType != InjectedHlslProgramType.Uknown) { var includes = GetIncludesLocation(sourceFile, includeType); foreach (var include in includes) { yield return(include); } } var cgIncludeFolder = CgIncludeDirectoryTracker.GetCgIncludeFolderPath(myUnityVersion); if (!cgIncludeFolder.ExistsDirectory) { yield break; } if (type == InjectedHlslProgramType.CGProgram) { var hlslSupport = cgIncludeFolder.Combine("HLSLSupport.cginc"); if (hlslSupport.ExistsFile) { yield return(new CppFileLocation(myCppExternalModule, hlslSupport)); } var variables = cgIncludeFolder.Combine("UnityShaderVariables.cginc"); if (variables.ExistsFile) { yield return(new CppFileLocation(myCppExternalModule, variables)); } } var lexer = CppLexer.Create(ProjectedBuffer.Create(buffer, range)); lexer.Start(); while (lexer.TokenType != null) { var tokenType = lexer.TokenType; if (tokenType is CppDirectiveTokenNodeType) { lexer.Advance(); var context = lexer.GetTokenText().TrimStart(); if (context.StartsWith("surface")) { var unityCG = cgIncludeFolder.Combine("UnityCG.cginc"); if (unityCG.ExistsFile) { yield return(new CppFileLocation(myCppExternalModule, unityCG)); } var lighting = cgIncludeFolder.Combine("Lighting.cginc"); if (lighting.ExistsFile) { yield return(new CppFileLocation(myCppExternalModule, lighting)); } var unityPbsLighting = cgIncludeFolder.Combine("UnityPBSLighting.cginc"); if (unityPbsLighting.ExistsFile) { yield return(new CppFileLocation(myCppExternalModule, unityPbsLighting)); } var autoLight = cgIncludeFolder.Combine("AutoLight.cginc"); if (autoLight.ExistsFile) { yield return(new CppFileLocation(myCppExternalModule, autoLight)); } break; } // TODO: optimization if we found vertex/fragment/geometry/hull/domain? } lexer.Advance(); } }