| /* |
| * 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(); |
| } |
| |
| } |