/*
* Copyright 2003-2016 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 jetbrains.mps.lang.pattern;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.mps.openapi.language.SConcept;
import org.jetbrains.mps.openapi.model.SNode;
import java.util.List;
/**
* Base class for matchers generated from PatternExpression
* @author Artem Tikhomirov
* @since 3.4
*/
public class GeneratedMatcher extends GeneratedMatchingPattern {
private final SNode myPatternNode;
private final boolean myHasAntiquotations;
protected final ValueContainer myValues = new ValueContainer();
protected final NodeMatcher myTopMatcher;
protected GeneratedMatcher(@NotNull SNode patternNode, boolean hasAntiquotations) {
// There are dubious uses of quoted 'this' as pattern e.g. in Type behaviors (e.g. Type.isSupersetOf), hence can't assert pattern is free-floating.
// Perhaps, those in need of quoted this shall be explicit to create a copy for pattern needs?
// assert patternNode.getModel() == null : "we don't want to deal with model access to pattern node, expect it to hang in the air";
myPatternNode = patternNode;
myHasAntiquotations = hasAntiquotations;
myTopMatcher = new NodeMatcher(myValues);
}
@Override
public Object getFieldValue(String varName) {
if (varName != null && varName.startsWith("patternVar_")) {
varName = varName.substring(11);
}
// FIXME compatibility code. Shall introduce typed getters and use them instead
SNode node = myValues.getNode(varName);
if (node != null) { return node; }
String p = myValues.getProperty(varName);
if (p != null) { return p; }
List<SNode> list = myValues.getList(varName);
if (list != null) { return list; }
return myValues.getRefTarget(varName);
}
@Override
public boolean match(SNode nodeToMatch) {
return myTopMatcher.match(myPatternNode, nodeToMatch);
}
@Override
public boolean hasAntiquotations() {
// there's only one dubious use of hasAntiquotations() method, in TS, where
// it refuses to coerce types matched against patterns with antiquotations. Nobody knows why.
return myHasAntiquotations;
}
@Override
public void fillFieldValuesFrom(GeneratedMatchingPattern pattern) {
if (getClass() == pattern.getClass()) {
myValues.reset(((GeneratedMatcher) pattern).myValues);
}
}
@Nullable
@Override
public SNode getMatchedNode(String varName) {
SNode rv = myValues.getNode(varName);
if (rv == null) {
rv = myValues.getRefTarget(varName);
}
return rv;
}
@Nullable
@Override
public String getMatchedProperty(String varName) {
return myValues.getProperty(varName);
}
@Nullable
@Override
public List<SNode> getMatchedList(String varName) {
return myValues.getList(varName);
}
@NotNull
@Override
public SConcept getConcept() {
return myPatternNode.getConcept();
}
}