blob: 4664c1f2a2e8a62d7dc4349cfc0b68adff2651d4 [file] [log] [blame]
package org.netbeans.modules.javascript2.jade.editor;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.netbeans.api.lexer.Token;
import org.netbeans.api.lexer.TokenHierarchy;
import org.netbeans.api.lexer.TokenSequence;
import org.netbeans.modules.javascript2.jade.editor.lexer.JadeTokenId;
import org.netbeans.modules.parsing.api.Embedding;
import org.netbeans.modules.parsing.api.Snapshot;
import org.netbeans.modules.parsing.spi.EmbeddingProvider;
/*
* 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.
*/
/**
*
* @author Petr Pisl
*/
@EmbeddingProvider.Registration(
mimeType="text/jade",
targetMimeType="text/javascript"
)
public class JadeJsEmbeddingProvider extends EmbeddingProvider {
private static final Logger LOGGER = Logger.getLogger(JadeJsEmbeddingProvider.class.getName());
private static final String JS_MIME_TYPE = "text/javascript"; //NOI18N
private static final String SEMICOLON_EOL = ";\n"; //NOI18N
private static final String EOL = "\n"; //NOI18N
private static final String SCRIPT_TAG_NAME = "script"; // NOI18N
@Override
public List<Embedding> getEmbeddings(Snapshot snapshot) {
TokenHierarchy<?> th = snapshot.getTokenHierarchy();
TokenSequence<JadeTokenId> ts = th.tokenSequence(JadeTokenId.jadeLanguage());
if (ts == null) {
LOGGER.log(
Level.WARNING,
"TokenHierarchy.tokenSequence(JadeTokenId.jadeLanguage()) == null " + "for static immutable Jade TokenHierarchy!\nFile = ''{0}'' ;snapshot mimepath=''{1}''",
new Object[]{snapshot.getSource().getFileObject().getPath(), snapshot.getMimePath()});
return Collections.emptyList();
}
ts.moveStart();
List<Embedding> embeddings = new ArrayList<>();
int from = -1;
int len = 0;
Token<JadeTokenId> lastTag = null;
Token<JadeTokenId> lastMixing = null;
while (ts.moveNext()) {
Token<JadeTokenId> token = ts.token();
if (token.id() == JadeTokenId.JAVASCRIPT) {
if (from < 0) {
from = ts.offset();
}
len += token.length();
} else {
if (from >= 0) {
if (lastMixing != null) {
wrapAsFnParameter(snapshot, embeddings, lastMixing.text().toString(), from, len);
} else {
embeddings.add(snapshot.create(from, len, JS_MIME_TYPE));
addNewLine(snapshot, embeddings, from + len - 1);
}
}
from = -1;
len = 0;
}
if (token.id() == JadeTokenId.TAG) {
lastTag = token;
lastMixing = null;
}
if (token.id() == JadeTokenId.MIXIN_NAME) {
lastTag = null;
lastMixing = token;
}
if (token.id() == JadeTokenId.PLAIN_TEXT_DELIMITER) {
// check whether there is not
if (lastTag != null && SCRIPT_TAG_NAME.equals(lastTag.text().toString().toLowerCase()) && ts.moveNext()) {
token = ts.token();
while (token.id() == JadeTokenId.EOL && ts.moveNext()) {
token = ts.token();
}
if (token.id() == JadeTokenId.PLAIN_TEXT || token.id() == JadeTokenId.JAVASCRIPT) {
embeddings.add(snapshot.create(ts.offset(), token.length(), JS_MIME_TYPE));
}
}
}
}
if (from >= 0) {
if (lastMixing != null) {
wrapAsFnParameter(snapshot, embeddings, lastMixing.text().toString(), from, len);
} else {
embeddings.add(snapshot.create(from, len, JS_MIME_TYPE));
addNewLine(snapshot, embeddings, from + len - 1);
}
}
if (embeddings.isEmpty()) {
return Collections.emptyList();
}
return Collections.singletonList(Embedding.create(embeddings));
}
private void addNewLine(Snapshot snapshot, List<Embedding> embeddings, int origOffset) {
CharSequence text = snapshot.getText();
int offset = origOffset;
while (offset > 0 && Character.isWhitespace(text.charAt(offset))) {
offset--;
}
if (offset > 0 ) {
char ch = text.charAt(offset);
if (ch == '{' || ch == '}' || ch == '[') {
embeddings.add(snapshot.create(EOL, JS_MIME_TYPE));
} else {
embeddings.add(snapshot.create(SEMICOLON_EOL, JS_MIME_TYPE));
}
}
}
private void wrapAsFnParameter(Snapshot snapshot, List<Embedding> embeddings, String fnName, int from, int len) {
embeddings.add(snapshot.create(fnName + "(", JS_MIME_TYPE)); //NOI18N
embeddings.add(snapshot.create(from, len, JS_MIME_TYPE));
embeddings.add(snapshot.create(");\n", JS_MIME_TYPE)); //NOI18N
}
@Override
public int getPriority() {
return 202;
}
@Override
public void cancel() {
// do nothig for now
}
}