Bug 773296 - Part 11: Give nsCSSParser and nsCSSScanner the ability to save/restore their current input state. r=dbaron

This adds functions to nsCSSParser and nsCSSScanner that let us save the
current input position (and corresponding information like line/column
number) and parser pushback, and be able to restore it later.  We'll use
this when rewinding the scanner after we first encounter a property with
a variable reference and go back to reparse it as a token stream.
This commit is contained in:
Cameron McCormack 2013-12-12 13:09:42 +11:00
parent 18286576a6
commit 199e5af323
3 changed files with 82 additions and 0 deletions

View File

@ -64,6 +64,12 @@ typedef void (* RuleAppendFunc) (css::Rule* aRule, void* aData);
static void AssignRuleToPointer(css::Rule* aRule, void* aPointer);
static void AppendRuleToSheet(css::Rule* aRule, void* aParser);
struct CSSParserInputState {
nsCSSScannerPosition mPosition;
nsCSSToken mToken;
bool mHavePushBack;
};
// Your basic top-down recursive descent style parser
// The exposed methods and members of this class are precisely those
// needed by nsCSSParser, far below.
@ -289,6 +295,18 @@ protected:
return mScanner->IsSVGMode();
}
/**
* Saves the current input state, which includes any currently pushed
* back token, and the current position of the scanner.
*/
void SaveInputState(CSSParserInputState& aState);
/**
* Restores the saved input state by pushing back any saved pushback
* token and calling RestoreSavedPosition on the scanner.
*/
void RestoreSavedInputState(const CSSParserInputState& aState);
bool GetToken(bool aSkipWS);
void UngetToken();
bool GetNextTokenLocation(bool aSkipWS, uint32_t *linenum, uint32_t *colnum);
@ -7144,6 +7162,22 @@ static const nsCSSProperty kOutlineRadiusIDs[] = {
eCSSProperty__moz_outline_radius_bottomLeft
};
void
CSSParserImpl::SaveInputState(CSSParserInputState& aState)
{
aState.mToken = mToken;
aState.mHavePushBack = mHavePushBack;
mScanner->SavePosition(aState.mPosition);
}
void
CSSParserImpl::RestoreSavedInputState(const CSSParserInputState& aState)
{
mToken = aState.mToken;
mHavePushBack = aState.mHavePushBack;
mScanner->RestoreSavedPosition(aState.mPosition);
}
bool
CSSParserImpl::ParseProperty(nsCSSProperty aPropID)
{

View File

@ -495,6 +495,32 @@ nsCSSScanner::Backup(uint32_t n)
#endif
}
void
nsCSSScanner::SavePosition(nsCSSScannerPosition& aState)
{
aState.mOffset = mOffset;
aState.mLineNumber = mLineNumber;
aState.mLineOffset = mLineOffset;
aState.mTokenLineNumber = mTokenLineNumber;
aState.mTokenLineOffset = mTokenLineOffset;
aState.mTokenOffset = mTokenOffset;
aState.mInitialized = true;
}
void
nsCSSScanner::RestoreSavedPosition(const nsCSSScannerPosition& aState)
{
MOZ_ASSERT(aState.mInitialized, "have not saved state");
if (aState.mInitialized) {
mOffset = aState.mOffset;
mLineNumber = aState.mLineNumber;
mLineOffset = aState.mLineOffset;
mTokenLineNumber = aState.mTokenLineNumber;
mTokenLineOffset = aState.mTokenLineOffset;
mTokenOffset = aState.mTokenOffset;
}
}
/**
* Skip over a sequence of whitespace characters (vertical or
* horizontal) starting at the current read position.

View File

@ -156,6 +156,22 @@ struct nsCSSToken {
void AppendToString(nsString& aBuffer) const;
};
// Represents an nsCSSScanner's saved position in the input buffer.
class nsCSSScannerPosition {
friend class nsCSSScanner;
public:
nsCSSScannerPosition() : mInitialized(false) { }
private:
uint32_t mOffset;
uint32_t mLineNumber;
uint32_t mLineOffset;
uint32_t mTokenLineNumber;
uint32_t mTokenLineOffset;
uint32_t mTokenOffset;
bool mInitialized;
};
// nsCSSScanner tokenizes an input stream using the CSS2.1 forward
// compatible tokenization rules. Used internally by nsCSSParser;
// not available for use by other code.
@ -236,6 +252,12 @@ class nsCSSScanner {
bool IsRecording() const;
#endif
// Stores the current scanner offset into the specified object.
void SavePosition(nsCSSScannerPosition& aState);
// Resets the scanner offset to a position saved by SavePosition.
void RestoreSavedPosition(const nsCSSScannerPosition& aState);
enum EOFCharacters {
eEOFCharacters_None = 0x0000,