blob: c22c9a81adfaa8b6eac65ea8e07741d58d784ae7 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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 org.netbeans.modules.javascript2.knockout.model;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.regex.Pattern;
import org.netbeans.modules.javascript2.types.api.DeclarationScope;
import org.netbeans.modules.javascript2.model.api.JsElement;
import org.netbeans.modules.javascript2.model.api.JsFunction;
import org.netbeans.modules.javascript2.model.api.JsObject;
import org.netbeans.modules.javascript2.types.api.TypeUsage;
import org.netbeans.modules.javascript2.model.spi.FunctionArgument;
import org.netbeans.modules.javascript2.model.spi.FunctionInterceptor;
import org.netbeans.modules.javascript2.model.spi.ModelElementFactory;
import org.netbeans.modules.javascript2.knockout.index.KnockoutCustomElement;
import org.netbeans.modules.javascript2.knockout.index.KnockoutIndexer;
import org.netbeans.modules.parsing.api.Snapshot;
import org.openide.filesystems.FileObject;
/**
*
* @author Roman Svitanic
*/
@FunctionInterceptor.Registration(priority = 400)
public class KnockoutRegisterInterceptor implements FunctionInterceptor {
private static final Pattern NAME_PATTERN = Pattern.compile("ko\\.components\\.register"); // NOI18N
@Override
public Pattern getNamePattern() {
return NAME_PATTERN;
}
@Override
public Collection<TypeUsage> intercept(Snapshot snapshot, String name, JsObject globalObject,
DeclarationScope scope, ModelElementFactory factory, Collection<FunctionArgument> args) {
if (!KnockoutIndexer.isScannerThread()) {
return Collections.emptyList();
}
String customElementName = null;
int functionOffset = -1;
int nameOffset = -1;
String fqnOfCustomElement;
for (FunctionArgument fArgument : args) {
switch (fArgument.getKind()) {
case STRING:
if (customElementName == null) {
// we expect that the first string parameter is the name of the custom element
customElementName = (String) fArgument.getValue();
nameOffset = fArgument.getOffset();
}
break;
case ANONYMOUS_OBJECT:
functionOffset = fArgument.getOffset();
break;
}
if (customElementName != null && functionOffset != -1) {
// we have probably found the custom component (element) registration
break;
}
}
if (customElementName != null) {
// we need to find the function itself
JsObject componentDecl = ModelUtils.findJsObject(globalObject, functionOffset);
if (componentDecl != null && componentDecl.getJSKind() == JsElement.Kind.ANONYMOUS_OBJECT && componentDecl.isDeclared()) {
fqnOfCustomElement = componentDecl.getFullyQualifiedName();
FileObject fo = globalObject.getFileObject();
Collection<String> componentParams = getComponentParameters(componentDecl);
if (fo != null) {
KnockoutIndexer.addCustomElement(fo.toURI(),
new KnockoutCustomElement(customElementName, fqnOfCustomElement, componentParams, fo.toURL(), nameOffset));
}
}
}
return Collections.emptyList();
}
private Collection<String> getComponentParameters(JsObject component) {
JsObject viewModel = component.getProperty("viewModel"); //NOI18N
List<JsObject> functionParams = null;
if (viewModel instanceof JsFunction) {
functionParams = (List<JsObject>) (((JsFunction) viewModel).getParameters());
} else if (viewModel instanceof JsObject) {
JsObject createViewModel = viewModel.getProperty("createViewModel"); //NOI18N
if (createViewModel != null) {
functionParams = (List<JsObject>) (((JsFunction) createViewModel).getParameters());
}
}
if (functionParams != null && !functionParams.isEmpty()) {
return functionParams.get(0).getProperties().keySet();
}
return Collections.emptyList();
}
}