mirror of
				https://github.com/TriliumNext/Notes.git
				synced 2025-10-31 21:11:30 +08:00 
			
		
		
		
	refactoring to ParserContext
This commit is contained in:
		
							parent
							
								
									a8d12f723f
								
							
						
					
					
						commit
						75d8627f1c
					
				| @ -1,3 +1,4 @@ | |||||||
|  | const ParsingContext = require("../src/services/search/parsing_context"); | ||||||
| const parser = require('../src/services/search/parser'); | const parser = require('../src/services/search/parser'); | ||||||
| 
 | 
 | ||||||
| describe("Parser", () => { | describe("Parser", () => { | ||||||
| @ -5,7 +6,7 @@ describe("Parser", () => { | |||||||
|         const rootExp = parser({ |         const rootExp = parser({ | ||||||
|             fulltextTokens: ["hello", "hi"], |             fulltextTokens: ["hello", "hi"], | ||||||
|             expressionTokens: [], |             expressionTokens: [], | ||||||
|             includingNoteContent: false |             parsingContext: new ParsingContext(false) | ||||||
|         }); |         }); | ||||||
| 
 | 
 | ||||||
|         expect(rootExp.constructor.name).toEqual("NoteCacheFulltextExp"); |         expect(rootExp.constructor.name).toEqual("NoteCacheFulltextExp"); | ||||||
| @ -16,7 +17,7 @@ describe("Parser", () => { | |||||||
|         const rootExp = parser({ |         const rootExp = parser({ | ||||||
|             fulltextTokens: ["hello", "hi"], |             fulltextTokens: ["hello", "hi"], | ||||||
|             expressionTokens: [], |             expressionTokens: [], | ||||||
|             includingNoteContent: true |             parsingContext: new ParsingContext(true) | ||||||
|         }); |         }); | ||||||
| 
 | 
 | ||||||
|         expect(rootExp.constructor.name).toEqual("OrExp"); |         expect(rootExp.constructor.name).toEqual("OrExp"); | ||||||
| @ -33,7 +34,7 @@ describe("Parser", () => { | |||||||
|         const rootExp = parser({ |         const rootExp = parser({ | ||||||
|             fulltextTokens: [], |             fulltextTokens: [], | ||||||
|             expressionTokens: ["#mylabel", "=", "text"], |             expressionTokens: ["#mylabel", "=", "text"], | ||||||
|             includingNoteContent: true |             parsingContext: new ParsingContext(true) | ||||||
|         }); |         }); | ||||||
| 
 | 
 | ||||||
|         expect(rootExp.constructor.name).toEqual("FieldComparisonExp"); |         expect(rootExp.constructor.name).toEqual("FieldComparisonExp"); | ||||||
| @ -46,7 +47,7 @@ describe("Parser", () => { | |||||||
|         const rootExp = parser({ |         const rootExp = parser({ | ||||||
|             fulltextTokens: [], |             fulltextTokens: [], | ||||||
|             expressionTokens: ["#first", "=", "text", "AND", "#second", "=", "text"], |             expressionTokens: ["#first", "=", "text", "AND", "#second", "=", "text"], | ||||||
|             includingNoteContent: true |             parsingContext: new ParsingContext(true) | ||||||
|         }); |         }); | ||||||
| 
 | 
 | ||||||
|         expect(rootExp.constructor.name).toEqual("AndExp"); |         expect(rootExp.constructor.name).toEqual("AndExp"); | ||||||
| @ -63,7 +64,7 @@ describe("Parser", () => { | |||||||
|         const rootExp = parser({ |         const rootExp = parser({ | ||||||
|             fulltextTokens: [], |             fulltextTokens: [], | ||||||
|             expressionTokens: ["#first", "=", "text", "#second", "=", "text"], |             expressionTokens: ["#first", "=", "text", "#second", "=", "text"], | ||||||
|             includingNoteContent: true |             parsingContext: new ParsingContext(true) | ||||||
|         }); |         }); | ||||||
| 
 | 
 | ||||||
|         expect(rootExp.constructor.name).toEqual("AndExp"); |         expect(rootExp.constructor.name).toEqual("AndExp"); | ||||||
| @ -80,7 +81,7 @@ describe("Parser", () => { | |||||||
|         const rootExp = parser({ |         const rootExp = parser({ | ||||||
|             fulltextTokens: [], |             fulltextTokens: [], | ||||||
|             expressionTokens: ["#first", "=", "text", "OR", "#second", "=", "text"], |             expressionTokens: ["#first", "=", "text", "OR", "#second", "=", "text"], | ||||||
|             includingNoteContent: true |             parsingContext: new ParsingContext(true) | ||||||
|         }); |         }); | ||||||
| 
 | 
 | ||||||
|         expect(rootExp.constructor.name).toEqual("OrExp"); |         expect(rootExp.constructor.name).toEqual("OrExp"); | ||||||
| @ -97,7 +98,7 @@ describe("Parser", () => { | |||||||
|         const rootExp = parser({ |         const rootExp = parser({ | ||||||
|             fulltextTokens: ["hello"], |             fulltextTokens: ["hello"], | ||||||
|             expressionTokens: ["#mylabel", "=", "text"], |             expressionTokens: ["#mylabel", "=", "text"], | ||||||
|             includingNoteContent: false |             parsingContext: new ParsingContext(false) | ||||||
|         }); |         }); | ||||||
| 
 | 
 | ||||||
|         expect(rootExp.constructor.name).toEqual("AndExp"); |         expect(rootExp.constructor.name).toEqual("AndExp"); | ||||||
| @ -114,7 +115,7 @@ describe("Parser", () => { | |||||||
|         const rootExp = parser({ |         const rootExp = parser({ | ||||||
|             fulltextTokens: [], |             fulltextTokens: [], | ||||||
|             expressionTokens: ["#first", "=", "text", "OR", ["#second", "=", "text", "AND", "#third", "=", "text"]], |             expressionTokens: ["#first", "=", "text", "OR", ["#second", "=", "text", "AND", "#third", "=", "text"]], | ||||||
|             includingNoteContent: false |             parsingContext: new ParsingContext(false) | ||||||
|         }); |         }); | ||||||
| 
 | 
 | ||||||
|         expect(rootExp.constructor.name).toEqual("OrExp"); |         expect(rootExp.constructor.name).toEqual("OrExp"); | ||||||
|  | |||||||
| @ -1,3 +1,6 @@ | |||||||
|  | "use strict"; | ||||||
|  | 
 | ||||||
|  | const ParsingContext = require('./parsing_context'); | ||||||
| const AndExp = require('./expressions/and'); | const AndExp = require('./expressions/and'); | ||||||
| const OrExp = require('./expressions/or'); | const OrExp = require('./expressions/or'); | ||||||
| const NotExp = require('./expressions/not'); | const NotExp = require('./expressions/not'); | ||||||
| @ -7,13 +10,13 @@ const NoteCacheFulltextExp = require('./expressions/note_cache_fulltext'); | |||||||
| const NoteContentFulltextExp = require('./expressions/note_content_fulltext'); | const NoteContentFulltextExp = require('./expressions/note_content_fulltext'); | ||||||
| const comparatorBuilder = require('./comparator_builder'); | const comparatorBuilder = require('./comparator_builder'); | ||||||
| 
 | 
 | ||||||
| function getFulltext(tokens, includingNoteContent, highlightedTokens) { | function getFulltext(tokens, parsingContext) { | ||||||
|     highlightedTokens.push(...tokens); |     parsingContext.highlightedTokens.push(...tokens); | ||||||
| 
 | 
 | ||||||
|     if (tokens.length === 0) { |     if (tokens.length === 0) { | ||||||
|         return null; |         return null; | ||||||
|     } |     } | ||||||
|     else if (includingNoteContent) { |     else if (parsingContext.includeNoteContent) { | ||||||
|         return new OrExp([ |         return new OrExp([ | ||||||
|             new NoteCacheFulltextExp(tokens), |             new NoteCacheFulltextExp(tokens), | ||||||
|             new NoteContentFulltextExp(tokens) |             new NoteContentFulltextExp(tokens) | ||||||
| @ -28,7 +31,7 @@ function isOperator(str) { | |||||||
|     return str.match(/^[=<>*]+$/); |     return str.match(/^[=<>*]+$/); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| function getExpression(tokens, highlightedTokens) { | function getExpression(tokens, parsingContext) { | ||||||
|     if (tokens.length === 0) { |     if (tokens.length === 0) { | ||||||
|         return null; |         return null; | ||||||
|     } |     } | ||||||
| @ -44,18 +47,18 @@ function getExpression(tokens, highlightedTokens) { | |||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         if (Array.isArray(token)) { |         if (Array.isArray(token)) { | ||||||
|             expressions.push(getExpression(token, highlightedTokens)); |             expressions.push(getExpression(token, parsingContext)); | ||||||
|         } |         } | ||||||
|         else if (token.startsWith('#') || token.startsWith('@')) { |         else if (token.startsWith('#') || token.startsWith('@')) { | ||||||
|             const type = token.startsWith('#') ? 'label' : 'relation'; |             const type = token.startsWith('#') ? 'label' : 'relation'; | ||||||
| 
 | 
 | ||||||
|             highlightedTokens.push(token.substr(1)); |             parsingContext.highlightedTokens.push(token.substr(1)); | ||||||
| 
 | 
 | ||||||
|             if (i < tokens.length - 2 && isOperator(tokens[i + 1])) { |             if (i < tokens.length - 2 && isOperator(tokens[i + 1])) { | ||||||
|                 const operator = tokens[i + 1]; |                 const operator = tokens[i + 1]; | ||||||
|                 const comparedValue = tokens[i + 2]; |                 const comparedValue = tokens[i + 2]; | ||||||
| 
 | 
 | ||||||
|                 highlightedTokens.push(comparedValue); |                 parsingContext.highlightedTokens.push(comparedValue); | ||||||
| 
 | 
 | ||||||
|                 const comparator = comparatorBuilder(operator, comparedValue); |                 const comparator = comparatorBuilder(operator, comparedValue); | ||||||
| 
 | 
 | ||||||
| @ -99,12 +102,10 @@ function getExpression(tokens, highlightedTokens) { | |||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| function parse({fulltextTokens, expressionTokens, includingNoteContent, highlightedTokens}) { | function parse({fulltextTokens, expressionTokens, parsingContext}) { | ||||||
|     highlightedTokens = highlightedTokens || []; |  | ||||||
| 
 |  | ||||||
|     return AndExp.of([ |     return AndExp.of([ | ||||||
|         getFulltext(fulltextTokens, includingNoteContent, highlightedTokens), |         getFulltext(fulltextTokens, parsingContext), | ||||||
|         getExpression(expressionTokens, highlightedTokens) |         getExpression(expressionTokens, parsingContext) | ||||||
|     ]); |     ]); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | |||||||
							
								
								
									
										18
									
								
								src/services/search/parsing_context.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								src/services/search/parsing_context.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,18 @@ | |||||||
|  | "use strict"; | ||||||
|  | 
 | ||||||
|  | class ParsingContext { | ||||||
|  |     constructor(includeNoteContent) { | ||||||
|  |         this.includeNoteContent = includeNoteContent; | ||||||
|  |         this.highlightedTokens = []; | ||||||
|  |         this.error = null; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     addError(error) { | ||||||
|  |         // we record only the first error, subsequent ones are usually consequence of the first
 | ||||||
|  |         if (!this.error) { | ||||||
|  |             this.error = error; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | module.exports = ParsingContext; | ||||||
| @ -42,15 +42,14 @@ async function findNotesWithExpression(expression) { | |||||||
|     return searchResults; |     return searchResults; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| function parseQueryToExpression(query, highlightedTokens) { | function parseQueryToExpression(query, parsingContext) { | ||||||
|     const {fulltextTokens, expressionTokens} = lexer(query); |     const {fulltextTokens, expressionTokens} = lexer(query); | ||||||
|     const structuredExpressionTokens = parens(expressionTokens); |     const structuredExpressionTokens = parens(expressionTokens); | ||||||
| 
 | 
 | ||||||
|     const expression = parser({ |     const expression = parser({ | ||||||
|         fulltextTokens, |         fulltextTokens, | ||||||
|         expressionTokens: structuredExpressionTokens, |         expressionTokens: structuredExpressionTokens, | ||||||
|         includingNoteContent: false, |         parsingContext | ||||||
|         highlightedTokens |  | ||||||
|     }); |     }); | ||||||
| 
 | 
 | ||||||
|     return expression; |     return expression; | ||||||
| @ -61,9 +60,12 @@ async function searchNotesForAutocomplete(query) { | |||||||
|         return []; |         return []; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     const highlightedTokens = []; |     const parsingContext = { | ||||||
|  |         includeNoteContent: false, | ||||||
|  |         highlightedTokens: [] | ||||||
|  |     }; | ||||||
| 
 | 
 | ||||||
|     const expression = parseQueryToExpression(query, highlightedTokens); |     const expression = parseQueryToExpression(query, parsingContext); | ||||||
| 
 | 
 | ||||||
|     if (!expression) { |     if (!expression) { | ||||||
|         return []; |         return []; | ||||||
| @ -73,7 +75,7 @@ async function searchNotesForAutocomplete(query) { | |||||||
| 
 | 
 | ||||||
|     searchResults = searchResults.slice(0, 200); |     searchResults = searchResults.slice(0, 200); | ||||||
| 
 | 
 | ||||||
|     highlightSearchResults(searchResults, highlightedTokens); |     highlightSearchResults(searchResults, parsingContext.highlightedTokens); | ||||||
| 
 | 
 | ||||||
|     return searchResults.map(result => { |     return searchResults.map(result => { | ||||||
|         return { |         return { | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 zadam
						zadam