diff --git a/json/gen/com/intellij/json/JsonParser.java b/json/gen/com/intellij/json/JsonParser.java index db05f6dacd3f..5046debe9f7b 100644 --- a/json/gen/com/intellij/json/JsonParser.java +++ b/json/gen/com/intellij/json/JsonParser.java @@ -1,18 +1,18 @@ // This is a generated file. Not intended for manual editing. package com.intellij.json; -import com.intellij.lang.ASTNode; import com.intellij.lang.PsiBuilder; import com.intellij.lang.PsiBuilder.Marker; -import com.intellij.lang.PsiParser; -import com.intellij.psi.tree.IElementType; -import com.intellij.psi.tree.TokenSet; - import static com.intellij.json.JsonElementTypes.*; import static com.intellij.json.psi.JsonParserUtil.*; +import com.intellij.psi.tree.IElementType; +import com.intellij.lang.ASTNode; +import com.intellij.psi.tree.TokenSet; +import com.intellij.lang.PsiParser; +import com.intellij.lang.LightPsiParser; @SuppressWarnings({"SimplifiableIfStatement", "UnusedAssignment"}) -public class JsonParser implements PsiParser { +public class JsonParser implements PsiParser, LightPsiParser { public ASTNode parse(IElementType t, PsiBuilder b) { parseLight(t, b); diff --git a/json/gen/com/intellij/json/psi/impl/JsonObjectImpl.java b/json/gen/com/intellij/json/psi/impl/JsonObjectImpl.java index 6a8aa94ac62f..a0a80e880247 100644 --- a/json/gen/com/intellij/json/psi/impl/JsonObjectImpl.java +++ b/json/gen/com/intellij/json/psi/impl/JsonObjectImpl.java @@ -11,7 +11,7 @@ import static com.intellij.json.JsonElementTypes.*; import com.intellij.json.psi.*; import com.intellij.navigation.ItemPresentation; -public class JsonObjectImpl extends JsonContainerImpl implements JsonObject { +public class JsonObjectImpl extends JsonObjectMixin implements JsonObject { public JsonObjectImpl(ASTNode node) { super(node); @@ -28,11 +28,6 @@ public class JsonObjectImpl extends JsonContainerImpl implements JsonObject { return PsiTreeUtil.getChildrenOfTypeAsList(this, JsonProperty.class); } - @Nullable - public JsonProperty findProperty(String name) { - return JsonPsiImplUtils.findProperty(this, name); - } - @Nullable public ItemPresentation getPresentation() { return JsonPsiImplUtils.getPresentation(this); diff --git a/json/src/com/intellij/json/psi/impl/JsonObjectMixin.java b/json/src/com/intellij/json/psi/impl/JsonObjectMixin.java new file mode 100644 index 000000000000..21ad2c9b870b --- /dev/null +++ b/json/src/com/intellij/json/psi/impl/JsonObjectMixin.java @@ -0,0 +1,60 @@ +/* + * Copyright 2000-2015 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.json.psi.impl; + +import com.intellij.json.psi.JsonObject; +import com.intellij.json.psi.JsonProperty; +import com.intellij.lang.ASTNode; +import com.intellij.psi.util.CachedValueProvider; +import com.intellij.psi.util.CachedValuesManager; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.HashMap; +import java.util.Map; + +/** + * @author Mikhail Golubev + */ +public abstract class JsonObjectMixin extends JsonContainerImpl implements JsonObject { + private final CachedValueProvider> myPropertyCache = + new CachedValueProvider>() { + @Nullable + @Override + public Result> compute() { + final Map cache = new HashMap(); + for (JsonProperty property : getPropertyList()) { + final String propertyName = property.getName(); + // Preserve the old behavior - return the first value in findProperty() + if (!cache.containsKey(propertyName)) { + cache.put(propertyName, property); + } + } + // Cached value is invalidated every time file containing this object is modified + return CachedValueProvider.Result.createSingleDependency(cache, JsonObjectMixin.this); + } + }; + + public JsonObjectMixin(@NotNull ASTNode node) { + super(node); + } + + @Nullable + @Override + public JsonProperty findProperty(@NotNull String name) { + return CachedValuesManager.getCachedValue(this, myPropertyCache).get(name); + } +} diff --git a/json/src/com/intellij/json/psi/impl/JsonPsiImplUtils.java b/json/src/com/intellij/json/psi/impl/JsonPsiImplUtils.java index d3814dc6c498..62dea13619d7 100644 --- a/json/src/com/intellij/json/psi/impl/JsonPsiImplUtils.java +++ b/json/src/com/intellij/json/psi/impl/JsonPsiImplUtils.java @@ -197,17 +197,6 @@ public class JsonPsiImplUtils { JsonPsiChangeUtils.removeCommaSeparatedFromList(myNode, myNode.getTreeParent()); } - @Nullable - public static JsonProperty findProperty(@NotNull JsonObject object, @NotNull String name) { - final Collection properties = PsiTreeUtil.findChildrenOfType(object, JsonProperty.class); - for (JsonProperty property : properties) { - if (property.getName().equals(name)) { - return property; - } - } - return null; - } - @NotNull public static String getValue(@NotNull JsonStringLiteral literal) { return StringUtil.unescapeStringCharacters(JsonPsiUtil.stripQuotes(literal.getText())); diff --git a/json/src/json.bnf b/json/src/json.bnf index 0d1d46d910a8..2e103f41eee8 100644 --- a/json/src/json.bnf +++ b/json/src/json.bnf @@ -62,6 +62,7 @@ object ::= '{' object_element* '}' { findProperty getPresentation ] + mixin="com.intellij.json.psi.impl.JsonObjectMixin" } // Hackity-hack to parse array elements and properties even if separating commas are missing,