andrewdavey/cassette — pull request #382 by johnnyreilly (2013-05-14 09:20:21+00:00)
Title: Allow control over references being added

Hi Andrew,

This is a change to allow control over what references should be added. I implemented this following our discussion ( https://groups.google.com/forum/?fromgroups=#!topic/cassette/SM3Rxh48D7Q ). The initial plan of implementing CustomParseReferences didn’t feel great because of the amount of copy-pasting involved due to internals.

After a little experimentation I tried a different approach could be taken to allow me to ensure that *.ts files were excluded. The change is to ParseReferences.cs but I’d describe it as minimal as it should have no impact on anyone using Cassette at present. It simple adds in another “hook” to allow fine grained control over what references should be added which users can override as they wish.

By the way, I did initially want ShouldAddReference to take ReferenceParser.ParsedReference as a parameter to follow the pattern established with ShouldParseAsset. If I had travelled that road it would have looked like this:

```cs
protected virtual bool ShouldAddReference(ReferenceParser.ParsedReference reference)
{
return true;
}
```

However that would have caused this error:

error CS0051: Inconsistent accessibility: parameter type 'Cassette.BundleProcessing.ReferenceParser.ParsedReference' is less accessible than method 'Cassette.BundleProcessing.ParseReferences.ShouldAddReference(Cassette.BundleProcessing.ReferenceParser.ParsedReference)'

And I didn’t want to change the accessibility of 'Cassette.BundleProcessing.ReferenceParser.ParsedReference' just to implement my change. So instead I just used a string to for the refererence path to keep the change as minimal as possible. (Interestingly it looks like all the current ShouldParseAsset overrides only operate on path anyway so I felt pretty okay about using that approach.)

I had hoped to create this for changing the pipeline in my own project:

```cs
public class ParseJavaScriptNotTypeScriptReferences : ParseReferences
{
protected override bool ShouldAddReference(string referencePath)
{
return !referencePath.EndsWith(".ts", StringComparison.OrdinalIgnoreCase); // Will exclude TypeScript files from being served
}

protected override bool ShouldParseAsset(IAsset asset)
{
return asset.Path.EndsWith(".js", StringComparison.OrdinalIgnoreCase);
}

protected override ICommentParser CreateCommentParser()
{
return new JavaScriptCommentParser();
}

internal override ReferenceParser CreateReferenceParser(ICommentParser commentParser)
{
return new JavaScriptReferenceParser(commentParser);
}
}
```

Unfortunately I couldn’t do this because CreateReferenceParser is internal and so overriding it in my own project wasn’t a go-er. So instead I’ve just subclassed ParseJavaScriptReferences (since I basically want to re-use it all) and put in my ShouldAddReference overload like this:

```cs
public class ParseJavaScriptNotTypeScriptReferences : ParseJavaScriptReferences
{
protected override bool ShouldAddReference(string referencePath)
{
return !referencePath.EndsWith(".ts", StringComparison.OrdinalIgnoreCase); // Will exclude TypeScript files from being served
}
}
```

And this does the job lovely when combined with this:

```cs
public class InsertIntoPipelineParseJavaScriptNotTypeScriptReferences : IBundlePipelineModifier
{
public IBundlePipeline Modify(IBundlePipeline pipeline)
{
pipeline.RemoveAt(1);
pipeline.Insert(1);
return pipeline;
}
}
```

I’d love for you to take this pull request as it solves my particular problem. And I suspect it may prove useful to others also. But no worries if you don’t want it.

Cheers,
John