Skip to content

Commit 63cd61f

Browse files
committed
Merge branch 'dynamic_directives'
2 parents 0682078 + fbcbf6d commit 63cd61f

File tree

101 files changed

+114053
-564
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

101 files changed

+114053
-564
lines changed

.editorconfig

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
root = true
2+
3+
[*]
4+
indent_style = space
5+
indent_size = 4

.gitignore

Lines changed: 4 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -1,65 +1,5 @@
1-
#################
2-
## Visual Studio
3-
#################
4-
5-
## Ignore Visual Studio temporary files, build results, and
6-
## files generated by popular Visual Studio add-ons.
7-
8-
# User-specific files
9-
*.suo
1+
Packages/
2+
bin/
3+
obj/
104
*.user
11-
*.sln.docstates
12-
13-
# Build results
14-
[Dd]ebug/
15-
[Rr]elease/
16-
*_i.c
17-
*_p.c
18-
*.ilk
19-
*.meta
20-
*.obj
21-
*.pch
22-
*.pdb
23-
*.pgc
24-
*.pgd
25-
*.rsp
26-
*.sbr
27-
*.tlb
28-
*.tli
29-
*.tlh
30-
*.tmp
31-
*.vspscc
32-
.builds
33-
*.dotCover
34-
*.sln.cache
35-
36-
# ReSharper is a .NET coding add-in
37-
_ReSharper*
38-
_dotCover*
39-
40-
# Others
41-
[Bb]in
42-
[Oo]bj
43-
44-
# Backup & report files from converting an old project file to a newer
45-
# Visual Studio version. Backup files are not needed, because we have git ;-)
46-
_UpgradeReport_Files/
47-
Backup*/
48-
UpgradeLog*.XML
49-
50-
src/packages/*
51-
!src/packages/repositories.config
52-
53-
############
54-
## Windows
55-
############
56-
57-
# Windows image file caches
58-
Thumbs.db
59-
60-
# Folder config file
61-
Desktop.ini
62-
63-
# NCrunch
64-
_NCrunch*
65-
5+
*.suo

src/resharper-angularjs.sln.DotSettings

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
22
<s:String x:Key="/Default/CodeStyle/FileHeader/FileHeaderRegionName/@EntryValue">license</s:String>
3-
<s:String x:Key="/Default/CodeStyle/FileHeader/FileHeaderText/@EntryValue">Copyright 2014 JetBrains s.r.o.&#xD;
3+
<s:String x:Key="/Default/CodeStyle/FileHeader/FileHeaderText/@EntryValue">Copyright 2015 JetBrains s.r.o.&#xD;
44
&#xD;
55
Licensed under the Apache License, Version 2.0 (the "License");&#xD;
66
you may not use this file except in compliance with the License.&#xD;
Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
#region license
2+
// Copyright 2015 JetBrains s.r.o.
3+
//
4+
// Licensed under the Apache License, Version 2.0 (the "License");
5+
// you may not use this file except in compliance with the License.
6+
// You may obtain a copy of the License at
7+
//
8+
// http://www.apache.org/licenses/LICENSE-2.0
9+
//
10+
// Unless required by applicable law or agreed to in writing, software
11+
// distributed under the License is distributed on an "AS IS" BASIS,
12+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
// See the License for the specific language governing permissions and
14+
// limitations under the License.
15+
#endregion
16+
17+
using System.Collections.Generic;
18+
using System.Linq;
19+
using JetBrains.DataFlow;
20+
using JetBrains.ReSharper.Psi;
21+
using JetBrains.ReSharper.Psi.Caches;
22+
using JetBrains.ReSharper.Psi.Files;
23+
using JetBrains.ReSharper.Psi.JavaScript.LanguageImpl;
24+
using JetBrains.ReSharper.Psi.JavaScript.Tree;
25+
using JetBrains.ReSharper.Psi.Tree;
26+
using JetBrains.Util;
27+
28+
namespace JetBrains.ReSharper.Plugins.AngularJS.Feature.Services.Caches
29+
{
30+
[PsiComponent]
31+
public class AngularJsCache : SimpleICache<AngularJsCacheItems>
32+
{
33+
public AngularJsCache(Lifetime lifetime, IPersistentIndexManager persistentIndexManager)
34+
: base(lifetime, persistentIndexManager, AngularJsCacheItems.Marshaller)
35+
{
36+
#if DEBUG
37+
// TODO: Useful for testing. Remove for release
38+
ClearOnLoad = true;
39+
#endif
40+
41+
CacheUpdated = new SimpleSignal(lifetime, "AngularJsCache");
42+
}
43+
44+
public ISimpleSignal CacheUpdated { get; private set; }
45+
46+
// TODO: Override Version when the format changes
47+
48+
protected override bool IsApplicable(IPsiSourceFile sf)
49+
{
50+
return sf.IsLanguageSupported<JavaScriptLanguage>();
51+
}
52+
53+
public override object Build(IPsiSourceFile sourceFile, bool isStartup)
54+
{
55+
if (!IsApplicable(sourceFile))
56+
return null;
57+
58+
// TODO: Check if this works for JS islands in HTML
59+
var jsFile = sourceFile.GetDominantPsiFile<JavaScriptLanguage>() as IJavaScriptFile;
60+
if (jsFile == null)
61+
return null;
62+
63+
var processor = new RecursiveElementProcessor();
64+
jsFile.ProcessDescendants(processor);
65+
return processor.CacheObject.IsEmpty ? null : processor.CacheObject;
66+
}
67+
68+
public override void Drop(IPsiSourceFile sourceFile)
69+
{
70+
// We can't use IsApplicable here, as the source file might be no longer valid.
71+
// But only clear the cache if the cache is changing
72+
if (Map.ContainsKey(sourceFile))
73+
ClearCache();
74+
base.Drop(sourceFile);
75+
}
76+
77+
public override void Merge(IPsiSourceFile sourceFile, object builtPart)
78+
{
79+
if (IsApplicable(sourceFile))
80+
{
81+
ClearCache();
82+
base.Merge(sourceFile, builtPart);
83+
}
84+
}
85+
86+
public IEnumerable<Directive> Directives
87+
{
88+
get
89+
{
90+
if (!LoadCompleted)
91+
return EmptyArray<Directive>.Instance;
92+
return Map.Values.SelectMany(v => v.Directives);
93+
}
94+
}
95+
96+
public IEnumerable<Filter> Filters
97+
{
98+
get
99+
{
100+
if (!LoadCompleted)
101+
return EmptyArray<Filter>.Instance;
102+
return Map.Values.SelectMany(v => v.Filters);
103+
}
104+
}
105+
106+
private void ClearCache()
107+
{
108+
CacheUpdated.Fire();
109+
}
110+
111+
private class RecursiveElementProcessor : IRecursiveElementProcessor
112+
{
113+
private readonly AngularJsCacheItemsBuilder cacheItemsBuilder;
114+
private readonly JsDocFileProcessor jsDocFileProcessor;
115+
private readonly JsInvocationProcessor jsInvocationProcessor;
116+
117+
public RecursiveElementProcessor()
118+
{
119+
cacheItemsBuilder = new AngularJsCacheItemsBuilder();
120+
jsDocFileProcessor = new JsDocFileProcessor(cacheItemsBuilder);
121+
jsInvocationProcessor = new JsInvocationProcessor(cacheItemsBuilder);
122+
}
123+
124+
public bool InteriorShouldBeProcessed(ITreeNode element)
125+
{
126+
return true;
127+
}
128+
129+
public void ProcessBeforeInterior(ITreeNode element)
130+
{
131+
var jsDocComment = element as IJavaScriptCommentNode;
132+
if (jsDocComment != null && jsDocComment.JsDocPsi != null && jsDocComment.JsDocPsi.JsDocFile != null)
133+
jsDocFileProcessor.ProcessJsDocFile(jsDocComment.JsDocPsi.JsDocFile);
134+
135+
var jsInvocation = element as IInvocationExpression;
136+
if (jsInvocation != null)
137+
jsInvocationProcessor.ProcessInvocationExpression(jsInvocation);
138+
139+
// TODO: What about TypeScript?
140+
// var tsInvocation = element as ITsInvocationExpression;
141+
}
142+
143+
public void ProcessAfterInterior(ITreeNode element)
144+
{
145+
}
146+
147+
public bool ProcessingIsFinished
148+
{
149+
get { return false; }
150+
}
151+
152+
public AngularJsCacheItems CacheObject
153+
{
154+
get { return cacheItemsBuilder.Build(); }
155+
}
156+
}
157+
}
158+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
using System.Collections.Generic;
2+
using System.Linq;
3+
using JetBrains.Util.PersistentMap;
4+
5+
namespace JetBrains.ReSharper.Plugins.AngularJS.Feature.Services.Caches
6+
{
7+
// All the cached items in a file, directives + filters
8+
public class AngularJsCacheItems
9+
{
10+
public static readonly IUnsafeMarshaller<AngularJsCacheItems> Marshaller =
11+
new UniversalMarshaller<AngularJsCacheItems>(Read, Write);
12+
13+
private readonly IList<Directive> directives;
14+
private readonly IList<Filter> filters;
15+
16+
public AngularJsCacheItems(IList<Directive> directives, IList<Filter> filters)
17+
{
18+
this.directives = directives;
19+
this.filters = filters;
20+
}
21+
22+
public IEnumerable<Directive> Directives { get { return directives; } }
23+
public IEnumerable<Filter> Filters { get { return filters; } }
24+
25+
public bool IsEmpty
26+
{
27+
get { return directives.Count == 0 && filters.Count == 0; }
28+
}
29+
30+
private static AngularJsCacheItems Read(UnsafeReader reader)
31+
{
32+
var directives = reader.ReadCollection(Directive.Read, count => new List<Directive>(count));
33+
var filters = reader.ReadCollection(Filter.Read, count => new List<Filter>(count));
34+
return new AngularJsCacheItems(directives, filters);
35+
}
36+
37+
private static void Write(UnsafeWriter writer, AngularJsCacheItems value)
38+
{
39+
writer.Write<Directive, ICollection<Directive>>((w, directive) => directive.Write(w), value.Directives.ToList());
40+
writer.Write<Filter, ICollection<Filter>>((w, filter) => filter.Write(w), value.Filters.ToList());
41+
}
42+
}
43+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
using System.Collections.Generic;
2+
3+
namespace JetBrains.ReSharper.Plugins.AngularJS.Feature.Services.Caches
4+
{
5+
public class AngularJsCacheItemsBuilder
6+
{
7+
private readonly IList<Directive> directives = new List<Directive>();
8+
private readonly IList<Filter> filters = new List<Filter>();
9+
10+
public AngularJsCacheItems Build()
11+
{
12+
return new AngularJsCacheItems(directives, filters);
13+
}
14+
15+
public void Add(Directive directive)
16+
{
17+
directives.Add(directive);
18+
}
19+
20+
public void Add(Filter filter)
21+
{
22+
filters.Add(filter);
23+
}
24+
}
25+
}

0 commit comments

Comments
 (0)